【问题标题】:MySQL Inner Join VS Left Join w/ IS NOT NULL?MySQL 内连接 VS 左连接 w/不为空?
【发布时间】:2014-04-29 09:53:42
【问题描述】:

以下是否有性能差异?

SELECT person.id
FROM person
LEFT JOIN address ON person.id = address.personID
WHERE address.personID IS NOT NULL

SELECT person.id
FROM person
INNER JOIN address ON person.id = address.personID

此查询应显示所有具有地址记录的人员 ID(并非全部都有)。如第二个示例所示,此处要做的合乎逻辑的事情是使用内部联接。由于不完全重要的原因(查询是从查询构建器生成的),我可能不得不使用第一种方法。

很好奇影响是什么。 MySQL 在 LEFT JOIN 时是否会做很多额外的工作,然后将该字段与 null 进行比较以减少集合?也许这就是 INNER JOIN 在幕后的工作方式?

【问题讨论】:

标签: mysql


【解决方案1】:

通常LEFT JOIN 将比INNER JOIN 花费更长的时间,因为LEFT JOIN 不仅会进行INNER JOIN 正在进行的比较,还会对不匹配的额外行进行比较(即null行)。所以除非有你想要的数据会被INNER JOIN过滤掉...我建议使用INNER JOIN

【讨论】:

    【解决方案2】:

    如下所示,这两个查询可能有不同的执行计划:

    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 的更好性能,但我还没有找到。

    【讨论】:

      【解决方案3】:

      这可能取决于 MySQL 的版本,因为每个版本都改进了优化器代码。这可能是旧版本为左外连接做更多工作的情况,导致person 的表扫描,即使找到特定的address 然后反向执行连接会更有效方向。

      @spencer7593 演示了两种连接类型导致优化器对表排序不同的情况,这意味着左连接强制首先访问左表。 (尽管在他的示例中,“使用连接缓冲区”表示连接没有索引,因此这可能是异常情况。)

      但是我已经看到优化器检测到查询等效于内部联接的情况,因为您在“外部”表的 WHERE 子句中有条件。因此,它为左外连接生成与内连接完全相同的优化计划,并允许对表进行重新排序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-12
        • 2019-07-16
        • 2013-01-30
        • 2011-07-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多