为什么自我加入比或更快?

时间:2010-10-20 17:43:40

标签: sql mysql query-optimization

我正在尝试过滤关系表以获得满足两个条件的表的子集(即:我想要color_ids为1或2的条目的所有id)。这是一张很强大的表格,所以我试图尽可能地优化它。

我想知道是否有人能在这种情况下解释我的发现:

为什么

SELECT DISTINCT a.id 
  FROM RelationshipTable as a 
  JOIN RelationshipTable as b ON b.id = a.id 
 WHERE a.color_id = 1 
   AND b.color_id = 2;

SELECT DISTINCT id 
  FROM RelationshipTable 
 WHERE color_id = 1 
    OR color_id = 2;
MySql 4.1 中的

2 个答案:

答案 0 :(得分:2)

第一个查询是不可能的,永远不会返回结果集。它基本上是说“给我表格中的所有记录,其中color_id为1,color_id为2”,这是永远不会发生的。

如果你想问一下

之间的区别
SELECT DISTINCT a.id 
  FROM RelationshipTable as a 
  JOIN RelationshipTable as b ON b.id = a.id 
 WHERE a.color_id = 1 
   OR b.color_id = 2;

SELECT DISTINCT color_id 
  FROM RelationshipTable 
 WHERE color_id = 1 
    OR color_id = 2;

在这种情况下,对于大型表,第一个总是慢于第二个。第一个导致表A的全表扫描,而第二个使用应该在where子句中使用的索引。

答案 1 :(得分:2)

这两个查询不是同一个,不应该给出相同的结果集。在第一个查询中,您需要满足两个条件的所有记录,您有一个color_id = 1的记录和一个color_id为2的记录,用于相同的ID。在第二个查询中,您将获得具有颜色ID的所有记录以及仅具有一个或另一个的所有记录。当然,因为你要求返回一个不同的字段,你可能看不到这一点。第二个问题无论如何都有些愚蠢,因为它可以表达为:

select 1 as color id 
union all
select 2

根本没打过桌子。那会让它超级快。