【问题标题】:LEFT JOIN much faster than INNER JOINLEFT JOIN 比 INNER JOIN 快得多
【发布时间】:2013-02-07 06:22:57
【问题描述】:

我有两张桌子 ->

  • 用户

    user_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
    username VARCHAR(200) NOT NULL
    
  • ping

    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 下面的Extracolumn 表示Using where; Using temporary; Using filesort,users 下表示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,而在用户下它是空的。

发生了什么?

【问题讨论】:

  • 每个需要多长时间?
  • 您意识到INNER JOINLEFT JOIN 是不同类型的查询,它们对您的结果集有非常不同的影响。
  • 你能详细解释一下@CAbbott
  • @CAbbott:一般来说是这样,但并非在所有特定情况下都是如此。示例 #1:如果您知道每个 ping 记录确实有对应的 users 记录。示例 #2:如果查询中的其他内容过滤掉所有没有 users 字段的记录。
  • @CAbbott - 你是对的。但是在这种情况下,两个表中的 user_id 都不是 NULL,会有什么不同吗?

标签: mysql left-join inner-join explain


【解决方案1】:

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

查询 1:(INNER JOIN):您说它只能返回表 ping 中的行,其中表 users 中有匹配的 user_id 值。这就是为什么有额外的usings 用于检查。

查询 2:(LEFT JOIN):您说它可以从表 ping 中返回 所有行任何匹配的行 em> user_id 来自表 users

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

【讨论】:

    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2018-07-10
      • 2019-10-09
      • 2010-12-21
      • 2015-03-03
      • 1970-01-01
      • 2023-01-02
      • 1970-01-01
      • 2021-11-21
      • 1970-01-01
      相关资源
      最近更新 更多