LEFT JOIN比INNER JOIN快得多

时间:2013-02-21 19:22:53

标签: mysql left-join inner-join explain

我有两张桌子 - >

  • 用户

    user_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
    username VARCHAR(200) NOT NULL
    
  • ping_id INT UNSIGNED NOT NULL AUTO_INCREMENT PPRIMARY KEY
    disqus_id VARCHAR(32) NOT NULL
    user_id INT UNSIGNED NOT NULL
    
    INDEX combo1(disqus_id,user_id)
    

我运行此查询 - >

EXPLAIN SELECT pings.*, username
          FROM pings
    INNER JOIN users USING(user_id)
         WHERE pings.disqus_id = 'post_168' AND user_id = '1'
      ORDER BY pings.ping_id DESC LIMIT 2

pimgs下的Extra列说Using where; Using temporary; Using filesort,用户说Using where; Using join buffer

我运行此查询 - >

EXPLAIN SELECT pings.*, username
          FROM pings
     LEFT JOIN users USING(user_id)
         WHERE pings.disqus_id = 'post_168' AND user_id = '1'
      ORDER BY pings.ping_id DESC LIMIT 2

pimgs下的Extra列显示Using where,而在用户下方则为空。

发生了什么事?

2 个答案:

答案 0 :(得分:2)

所以如果您使用user_id必须在两个表中,但是左连接将返回表a中的值而不是表b中的值

以下两个子句在语义上是相同的:

a LEFT JOIN b USING (c1,c2,c3)
a LEFT JOIN b ON a.c1=b.c1 AND a.c2=b.c2 AND a.c3=b.c3

答案 1 :(得分:2)

您正在创建2个不同的查询,这些查询有两组不同的要求,可能会产生相同的结果集:

查询1:(内部联接):您声明它只能返回表ping中的行,其中表user_id值匹配{ {1}}。这就是为什么有额外的users进行检查的原因。

查询2 :( LEFT JOIN):您声明它可以从表using返回匹配的任何行所有行 ping来自表格user_id

这里的区别问题是你是否要求在第二个表中存在匹配值。在查询1中,它必须添加额外的检查以确保存在匹配值,在查询2中,它不会。