以下是否存在性能差异?
SELECT person.id
FROM person
LEFT JOIN address ON person.id = address.personID
WHERE address.personID IS NOT NULL
VS
SELECT person.id
FROM person
INNER JOIN address ON person.id = address.personID
此查询应显示所有具有地址记录的人员ID(并非所有人都这样做)。这里合乎逻辑的做法是使用内部连接,如第二个示例所示。由于不完全重要的原因(查询是从查询构建器生成的),我可能必须使用第一种方法。
好奇是什么影响。当LEFT JOIN' s然后将该字段与null进行比较以减少设置时,MySQL是否会做很多额外的工作?也许这就是INNER JOIN如何在幕后工作?
答案 0 :(得分:3)
如下所示,这两个查询可能存在不同的执行计划:
SELECT p.*, s.*
FROM p
LEFT
JOIN s ON s.col = p.col
WHERE s.col IS NOT NULL
SELECT p.*, s.*
FROM p
INNER
JOIN s ON s.col = p.col
id select_type table type poss key key_len ref rows Extra
-- ----------- ------ ---- ---- ---- ------- ----- ---- --------
1 SIMPLE p ALL - - - - 3
1 SIMPLE s ref s_ix s_ix 9 p.col 1
id select_type table type poss key key_len ref rows Extra
-- ----------- ------ ---- ---- ---- ------- ----- ---- -----------------------------
1 SIMPLE s ALL s_ix - - - 2
1 SIMPLE p ALL p_ix - - - 3 Using where; Using join buffer
因此,我们必须得出结论,性能可能会有所不同。在小套装上,差异可以忽略不计。大型集合可能会在性能方面表现出显着差异;我们希望INNER JOIN更有效率。完全有可能有一个测试用例表明LEFT JOIN的性能更好,但我还没有找到它。
答案 1 :(得分:2)
它可能取决于MySQL的版本,因为优化器代码在每个版本中都得到了改进。这可能是旧版本对左外连接执行更多工作的情况,导致person
的表扫描,即使查找特定address
更有效,然后执行加入反向。
@ spencer7593演示了两种连接类型导致优化器排序不同的情况,这意味着左连接会强制首先访问左表。 (虽然在他的例子中,"使用连接缓冲区"表示连接没有索引,所以这可能是异常。)
但是我已经看到优化器检测到查询等同于内连接的情况,因为你在"外部"的WHERE子句中有条件。表。因此,它为左外连接生成与内连接完全相同的优化计划,并允许表重新排序。
答案 2 :(得分:0)
一般LEFT JOIN
需要的时间超过INNER JOIN
,因为LEFT JOIN
不仅要进行INNER JOIN
正在进行的比较,还要对额外的行进行比较不匹配(即null
行)。所以,除非您想要的数据会被INNER JOIN
过滤掉...我建议您使用INNER JOIN