下面哪个查询更快?
不存在:
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
我想我还是用“不存在”吧。
我有一个大约有120,000条记录的表,需要只选择那些不存在的(匹配一个varchar列),在其他四个表中,行数约为1500,4000,40000,200。所有相关的表在相关的Varchar列上都有唯一的索引。
NOT IN花了大约10分钟,NOT EXISTS花了4秒。
我有一个递归查询,它可能有一些未调优的部分,这可能是10分钟的贡献,但另一个选项花了4秒解释,至少对我来说,NOT EXISTS是更好的,或者至少,IN和EXISTS并不完全相同,在继续代码之前总是值得检查。
还要注意,当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