以下是否存在性能差异?
SELECT person.id
FROM person
LEFT JOIN address ON person.id = address.personID
WHERE address.personID IS NOT NULL
Run Code Online (Sandbox Code Playgroud)
VS
SELECT person.id
FROM person
INNER JOIN address ON person.id = address.personID
Run Code Online (Sandbox Code Playgroud)
此查询应显示具有地址记录的所有人员ID(并非所有人都这样做).这里合乎逻辑的做法是使用内部连接,如第二个示例所示.由于不完全重要的原因(查询是从查询构建器生成的),我可能必须使用第一种方法.
好奇是什么影响.MySQL在LEFT JOIN中做了很多额外的工作,然后将该字段与null进行比较以减少设置吗?也许这就是INNER JOIN如何在幕后工作?
如下所示,这两个查询可能有不同的执行计划:
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
Run Code Online (Sandbox Code Playgroud)
因此,我们必须得出结论,性能可能存在差异。在小型设备上,差异可以忽略不计。大集合可能会在性能上表现出显着差异;我们希望 INNER JOIN 更加高效。完全有可能有一个测试用例可以证明 LEFT JOIN 的更好性能,但我还没有找到。
这可能取决于MySQL的版本,因为优化器代码在每个版本中都有改进。这可能是旧版本对左外连接做了更多工作,导致表扫描,即使找到特定的然后以相反方向进行连接person会更有效。address
@spencer7593 演示了两种连接类型导致优化器对表进行不同排序的情况,这意味着左连接强制首先访问左表。(尽管在他的示例中,“使用连接缓冲区”表明连接没有索引,因此这可能是异常情况。)
但我见过优化器检测到查询相当于内部联接的情况,因为“外部”表的 WHERE 子句中有条件。因此,它为左外连接生成与内连接完全相同的优化计划,并允许表重新排序。
| 归档时间: |
|
| 查看次数: |
4530 次 |
| 最近记录: |