INTERSECT/EXCEPT VS. IN/NOT IN

我真是OLD到死,虽然记得以前肯定看到过INTERSECT/EXCEPT这两个关键字,前不久还在羡慕Oracle有+/-集合操作符而SQL Server怎么竟然没有。。。现在想想难怪当初微软面试的时候面试官告诉我最好了解一下SQL Server 2005新的函数。。。

下面翻译一下http://www.sqlstuff.dk/post/intersect-except-versus-in-not-in.aspx,对INTERSECT/EXCEPT与IN/NOT IN进行比较。

SQL Server有两个有用的,用于找到两个表之间共有与差异行的函数:EXCEPT与INTERSECT。EXCEPT返回属于第一个表而不属于第二个表的行,而INTERSECT返回第一个和第二个表的交集。但它们的性能如何?

实际生活中我发现我很少有机会比较两个拥有完全相同数据列的表,但偶尔也会有这种需求。(难道这两个函数基本只在面试和考试中派用场。。。?)但是大多数情况下,这些行都有主键或其他索引,所以我一般自己只用IN和NOT IN。

为了测试,我建立了两个测试表:


 

DECLARE @I INT 
SET @I = 0 

WHILE @I < 10000 BEGIN 
 
IF @I % 5 <> 0 
  
INSERT INTO Table1 VALUES (@IREPLICATE('A'10)) 
 
IF @I % 4 <> 0 INSERT 
  
INTO Table2 VALUES (@IREPLICATE('A'10)) 
 
SET @I = @I + 1 
END   

我没有建立索引。
接下来我要查询属于表1不属于表2的行。由于我知道ID是一个唯一键(unique key),就只适用NOT IN。

SELECT * 
FROM Table1 
WHERE ID NOT IN ( 
 
SELECT ID FROM Table2 

GO 

SELECT * FROM Table1 
EXCEPT 
SELECT * FROM Table2 
GO   

这样是人都知道肯定NOT IN效率差的。比率差不多是23% vs. 77%,3.3倍左右。

如果我不仅需要确认ID,还需要确认VALUE,查询语句如下:


 

SELECT * 
FROM Table1 
WHERE ID NOT IN ( 
 
SELECT ID FROM Table2 

OR [Value] NOT IN ( 
 
SELECT [Value] FROM Table2 

GO 

SELECT * FROM Table1 
EXCEPT 
SELECT * FROM Table2 
GO   

差异进一步拉大。22% vs. 78%。

INTERSECT的结果也大同小异。

原文地址:https://www.cnblogs.com/galaxyyao/p/1604679.html