简体   繁体   English

MySQL - 在没有性能的情况下使用左连接计数

[英]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. 我正在使用Laravel框架,因此大多数查询都不是手工生成的。

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 table有大约100k记录执行0,7s而其他

SELECT count(*) FROM table

executes 0,01s 执行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? 问题是 - 是否可以向查询中添加任何内容以使查询更快地执行(告诉MySQL在没有WHERE条件时忽略LEFT JOINS)和第二个问题 - 为什么MySQL在这种情况下使用连接时全部联接是LEFT,没有位置?

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. 这里的问题是我向查询添加了许多条件,因此有时会使用很多WHERE(最多20-30个条件),并且必须使用某些条件连接。

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. 目前我无法检查索引(很可能它们可能导致问题)但我仍然感到惊讶的是MySQL在这种情况下不会忽略连接。

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. 作为一种解决方法,在这种情况下,当没有使用条件时,或者对于不需要连接的大约10-15个条件,我不会使用左连接进行计数,但对于其他条件,我应该为所需的连接创建map

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. AS @Gordon Linoff在答案中提到连接不会创建任何额外的行,如果没有连接的查询生成10行,如果将使用这些连接,将返回完全相同的行。

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? MySQL如何知道两个表中没有重复值,这将导致行的乘法?

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. 我很确定MySQL没有实现这种优化,但可能还有其他数据库引擎。

Am not sure but couldn't you brought some conditions in where clause to join conditions? 我不确定但是你不能在where子句中加入条件加入条件吗?

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. 我认为第二个的表现要好得多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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