Reputation: 1717
I am combining three tables - persons, properties, totals - using LEFT JOIN
. I find the following query to be really fast but it does not give me all rows from table-1 for which there is no corresponding data in table-2 or table-3. Basically, it gives me only rows where there is data in table-2 and table-3.
SELECT a.*, b.propery_address, c.person_asset_total
FROM persons AS a
LEFT JOIN properties AS b ON a.id = b.person_id
LEFT JOIN totals AS c ON a.id = c.person_id
WHERE a.city = 'New York' AND
c.description = 'Total Immovable'
Whereas the following query gives me the correct result by including all rows from table-1 irrespective of whether there is corresponding data or no data from table-2 and table-3. However, this query is taking a really long processing time.
FROM persons AS a
LEFT JOIN
properties AS b ON a.id = b.person_id
LEFT JOIN
(SELECT person_id, person_asset_total
FROM totals
WHERE description = 'Total Immovable'
) AS c ON a.id = c.person_id
WHERE a.city = 'New York'
Is there a better way to write a query that will give data equivalent to second query but with speed of execution equivalent to the first query?
Upvotes: 0
Views: 3790
Reputation: 1269773
Don't use a subquery:
SELECT p.*, pr.propery_address, t.person_asset_total
FROM persons p LEFT JOIN
properties pr
ON p.id = pr.person_id LEFT JOIN
totals t
ON a.id = c.person_id AND t.description = 'Total Immovable'
WHERE p.city = 'New York';
Your approach would be fine in almost any other database. However, MySQL materializes "derived tables", which makes them much harder to optimize. The above has the same effect.
You will also notice that I changed the table aliases to be abbreviations for the table names. This makes the query much easier to follow.
Upvotes: 4