今天我发现了我正在工作的项目的性能问题。我正在使用Laravel框架,因此大多数查询都不是手工生成的。
问题:
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
其中table
有大约100k条记录执行0,7s
而
SELECT count(*) FROM table
执行0,01s
因此性能损失巨大。问题是 - 是否可以向查询中添加任何内容以使查询更快地执行(告诉MySQL在没有WHERE条件时忽略LEFT JOINS)和第二个问题 - 为什么MySQL在这种情况下使用连接时全部联接是LEFT,没有位置?
这里的问题是我在查询中添加了很多条件,所以有时会使用很多WHERE(最多20-30个条件),并且必须使用某些条件连接。
目前我无法检查索引(它们很可能导致问题)但我仍然感到惊讶的是MySQL在这种情况下不会忽略连接。
作为一种解决方法,在这种情况下,当没有使用条件时,或者对于不需要连接的大约10-15个条件,我不会使用左连接进行计数,但对于其他条件,我应该为连接创建map
需要的。
AS @Gordon Linoff在回答连接中提到不会创建任何额外的行,如果没有连接的查询生成10行,如果将使用这些连接,将返回完全相同的行。
答案 0 :(得分:2)
这两个查询不相同。 MySQL如何知道两个表中没有重复的值,这会导致行的乘法?
实际上有办法。如果在第二个表中声明连接键是唯一的,那么数据库引擎可以知道连接是不必要的。我非常确定MySQL没有实现这种优化,但可能还有其他数据库引擎。
答案 1 :(得分:0)
我不确定但是你不能在where子句中加入条件来加入条件吗?
例如,我认为以下两个查询的性能不同,但在输出情况下它们是等效的:
select *
from A
left join B on A.id=B.ID
where B.field=value
和
from A
left join B on A.id=B.ID AND B.field=value
我认为第二个的表现要好得多。