MySQL内连接VS左连接w / IS NOT NULL?

时间:2014-03-21 20:21:53

标签: mysql

以下是否存在性能差异?

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如何在幕后工作?

3 个答案:

答案 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