简体   繁体   中英

MySQL - count with left join without where performance

Today I found performance issue on the project I'm working. I'm using Laravel framework so most queries are not generated by hand.

The problem:

SELECT count(*) FROM table LEFT JOIN a ON table.a_id= a.id LEFT JOIN b ON table.b_id = b.id LEFT JOIN c ON table.c_id = c.id

where table has about 100k records executes 0,7s whereas

SELECT count(*) FROM table

executes 0,01s

So the performance loss is huge. The question is - is it possible to add anything to the query to make query being executed faster (to tell MySQL to ignore LEFT JOINS when there are no WHERE conditions) and the second question - why MySQL uses joins at all in this case when all joins are LEFT and there is no where?

The problem here is that I add many conditions to the query so sometimes many WHERE are used (up to 20-30 conditions) and for some of conditions joins MUST be used.

At the moment I couldn't check indexes (it's quite possible they can cause the problem) but I'm still surprised that MySQL doesn't ignore joins in that case.

As a workaround I'll not use left joins for count in this case when no conditions are used or for about 10-15 conditions where no joins are needed but for others I should create map for joins that are needed.

AS @Gordon Linoff mentioned in the answer joins won't create any extra rows, if query without joins generate 10 rows, the exact same of rows will be returned if those joins will be used.

The two queries are not equivalent. How does MySQL know that there are no duplicate values in the two tables, that will result in a multiplication of rows?

There actually is a way. If the join key is declared to be unique in the second table, then the database engine could know that the join is unnecessary. I'm pretty sure MySQL does not implement this optimization, but there may be other database engines that do.

Am not sure but couldn't you brought some conditions in where clause to join conditions?

for instance I think the below two queries have not same performance but they are equivalent in case of output:

select * 
from A
left join B on A.id=B.ID
where B.field=value

and

from A
left join B on A.id=B.ID AND B.field=value

I think the performance of second one should be much better.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM