在SQL Server中,not(列Name ='value')和列Name<>'value'之间有什么区别?

时间:2012-01-11 09:06:49

标签: sql sql-server tsql

在SQL Server where子句中,无论您编写not(columnName='value')还是columnName<>'value',都会有所不同?

我在考虑表现。

有人告诉我,当使用Not()时,它可能不会使用它可能与&lt;&gt;一起使用的索引。

3 个答案:

答案 0 :(得分:4)

最好的办法是检查执行计划。当我在SQL Server 2008中测试以下内容时,他们给出了相同的计划(并且两者都被转换为2个范围搜索。因此<> x转换为> x< x

CREATE TABLE T
  (
     C INT,
     D INT,
     PRIMARY KEY(C, D)
  )

INSERT INTO T
SELECT 1,
       1
UNION ALL
SELECT DISTINCT 2,
                number
FROM   master..spt_values

SELECT *
FROM   T
WHERE  NOT ( C = 2 )

SELECT *
FROM   T
WHERE  ( C <> 2 )  

给出

  |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1010], [Expr1011], [Expr1012]))
       |--Merge Interval
       |    |--Sort(TOP 2, ORDER BY:([Expr1013] DESC, [Expr1014] ASC, [Expr1010] ASC, [Expr1015] DESC))
       |         |--Compute Scalar(DEFINE:([Expr1013]=((4)&[Expr1012]) = (4) AND NULL = [Expr1010], [Expr1014]=(4)&[Expr1012], [Expr1015]=(16)&[Expr1012]))
       |              |--Concatenation
       |                   |--Compute Scalar(DEFINE:([Expr1005]=NULL, [Expr1006]=CONVERT_IMPLICIT(int,[@1],0), [Expr1004]=(10)))
       |                   |    |--Constant Scan
       |                   |--Compute Scalar(DEFINE:([Expr1008]=CONVERT_IMPLICIT(int,[@1],0), [Expr1009]=NULL, [Expr1007]=(6)))
       |                        |--Constant Scan
       |--Clustered Index Seek(OBJECT:([test].[dbo].[T].[PK__T__B86D18326339AFF7]), SEEK:([test].[dbo].[T].[C] > [Expr1010] AND [test].[dbo].[T].[C] < [Expr1011]) ORDERED FORWARD)

Plan

答案 1 :(得分:3)

优化者有时可以通过将表达式转换为不同的表达方式来提高眉毛,但速度更快。

比如说,如果从具有很少唯一值的表中进行选择,并且SQL Server可以确定实际上很少有唯一值(例如,123 ),然后where x<>2甚至可能最终转换为类似[Union1004] = (1) OR [Union1004] = (3)的某些内容,这与初始表达式有些无关,但会产生想要的结果。

也就是说,不要担心这种性能水平。无论如何,SQL Server都会破坏它。

答案 2 :(得分:1)

如果两个参数都具有 NON-NULL 值,则它们是等效的

<强> BUT

即使有任何一个空值 - 它们仍然是等价的,但你不能依赖它们8 - )

上面引用的是 NOT TRUE ,感谢@Martin Smith

  

唯一重要但性能不同的 - 如果使用过滤索引,则优化程序搜索过滤后的索引   规范化条件,但简单的词汇等价。

     

因此,如果您使用语句WHERE columnName<>'value'过滤了columnName的索引,那么如果您编写columnName<>'value'   在选择的WHERE中 - 可以使用索引,具体取决于其他   条件,如果你写not(columnName='value') - 索引甚至   不会被视为

不要试图帮助优化者完成其工作。它非常复杂,所以 - 不要混淆8-)或者如果你真的知道你究竟在做什么以及它如何影响优化器的行为