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  ( @I REPLICATE ( ' A ' 10 )) 
 
IF   @I   %   4   <>   0   INSERT  
  
INTO  Table2  VALUES  ( @I REPLICATE ( ' 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的结果也大同小异。

你可能感兴趣的:(intersect)