2012-01-11 86 views

回答

4

最好的事情是檢查執行計劃。當我在SQL Server 2008中測試以下內容時,他們給出了相同的計劃(並且都轉換爲2個範圍查找。所以<> x被轉換爲> x OR < 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

3

優化器有時可以通過瘋狂的技巧將表情翻譯成不同的東西,但速度更快。

說,如果你從幾個唯一值的表中選擇,和SQL Server有辦法弄清楚其實有幾個唯一值(比方說,123),然後where x<>2甚至可能最終轉化爲成才如[Union1004] = (1) OR [Union1004] = (3),這與初始表達式有些不相關,但會產生想要的結果。

也就是說,不要擔心這個級別的性能。無論如何,SQL Server將破壞它。

1

如果兩個參數有非NULL值 - 他們相當於

即使任何具有空值 - 他們依然等價的,但你不能依賴他們8-)

中引用上面的提到的是不是真的,感謝@馬丁史密斯

唯一重要的是性能不同 - 如果您使用過濾索引,則優化器搜索已過濾索引而不是 使條件正常化,但簡單詞法等價。

所以,如果你有一個說法WHERE columnName<>'value'過濾上COLUMNNAME指數則在情況下,如果你選擇在哪裏寫columnName<>'value' - 索引可以使用,這取決於其他 條件,如果你寫not(columnName='value') - 該指數甚至 將不考慮

不要試圖幫助優化器來完成其工作。這是非常複雜的,所以 - 不要混淆8-)或者做,如果你真的知道正是你在做什麼,以及它如何影響優化的行爲做

+0

奧列格的道歉,我已澄清我的問題所以不知道你現在答案是相關的。 – 2012-01-11 09:50:32

+0

仍然是一樣的,性能不會取決於你如何編寫,但在什麼樣的索引和統計你有 – 2012-01-11 09:52:00

+0

改進的答案有點 – 2012-01-11 09:55:41

相關問題