下面哪个查询更快?

不存在:

SELECT ProductID, ProductName 
FROM Northwind..Products p
WHERE NOT EXISTS (
    SELECT 1 
    FROM Northwind..[Order Details] od 
    WHERE p.ProductId = od.ProductId)

或不在:

SELECT ProductID, ProductName 
FROM Northwind..Products p
WHERE p.ProductID NOT IN (
    SELECT ProductID 
    FROM Northwind..[Order Details])

查询执行计划表示它们都做相同的事情。如果是这样的话,推荐哪种形式?

这是基于北风的数据库。

(编辑)

刚找到这篇有用的文章: http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210.aspx

我想我还是用“不存在”吧。


当前回答

事实上,我相信这是最快的:

SELECT ProductID, ProductName 
    FROM Northwind..Products p  
          outer join Northwind..[Order Details] od on p.ProductId = od.ProductId)
WHERE od.ProductId is null

其他回答

如果执行计划说它们是一样的,它们就是一样的。使用任何一个能让你的意图更明显的方法——在这种情况下,使用第二个。

它们非常相似,但并不完全相同。

在效率方面,我发现左join is null语句更有效(当要选择大量行时)

还要注意,当NOT IN为null时,NOT IN并不等同于NOT EXISTS。

这篇文章解释得很好

http://sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in/

When the subquery returns even one null, NOT IN will not match any rows. The reason for this can be found by looking at the details of what the NOT IN operation actually means. Let’s say, for illustration purposes that there are 4 rows in the table called t, there’s a column called ID with values 1..4 WHERE SomeValue NOT IN (SELECT AVal FROM t) is equivalent to WHERE SomeValue != (SELECT AVal FROM t WHERE ID=1) AND SomeValue != (SELECT AVal FROM t WHERE ID=2) AND SomeValue != (SELECT AVal FROM t WHERE ID=3) AND SomeValue != (SELECT AVal FROM t WHERE ID=4) Let’s further say that AVal is NULL where ID = 4. Hence that != comparison returns UNKNOWN. The logical truth table for AND states that UNKNOWN and TRUE is UNKNOWN, UNKNOWN and FALSE is FALSE. There is no value that can be AND’d with UNKNOWN to produce the result TRUE Hence, if any row of that subquery returns NULL, the entire NOT IN operator will evaluate to either FALSE or NULL and no records will be returned

我有一个大约有120,000条记录的表,需要只选择那些不存在的(匹配一个varchar列),在其他四个表中,行数约为1500,4000,40000,200。所有相关的表在相关的Varchar列上都有唯一的索引。

NOT IN花了大约10分钟,NOT EXISTS花了4秒。

我有一个递归查询,它可能有一些未调优的部分,这可能是10分钟的贡献,但另一个选项花了4秒解释,至少对我来说,NOT EXISTS是更好的,或者至少,IN和EXISTS并不完全相同,在继续代码之前总是值得检查。

这取决于. .

SELECT x.col
FROM big_table x
WHERE x.key IN( SELECT key FROM really_big_table );

不会相对较慢,也没有太多限制查询检查的大小,看看他们的键是否在。在这种情况下,存在是可取的。

但是,根据DBMS的优化器,这可能没有什么不同。

作为一个例子,当存在更好

SELECT x.col
FROM big_table x
WHERE EXISTS( SELECT key FROM really_big_table WHERE key = x.key);
  AND id = very_limiting_criteria