0

我有两张桌子->

  • 用户

    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

Extrapimgs下的列表示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

Extrapimgs下的列表示Using where,而 users 下的列是空的。

怎么了?

4

2 回答 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
于 2013-02-21T19:34:42.227 回答
2

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

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

查询 2: (LEFT JOIN):您说它可以返回table 中的所有行ping以及与table匹配的任何行user_idusers

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

于 2013-02-21T19:45:43.760 回答