2010-06-24 53 views
9

什麼是在SQL查詢中檢查列的空值或值的有效方法。考慮具有索引的整數列column的sql表table@value可以是一些整數或空例如:16或null。用於比較SQL中列的NULL或值的有效方法

查詢1:不確定,但似乎不應該依賴SQL中的短路。但是,當@value是某個整數或null時,下面的查詢總是可以正常工作。

select * from 
table 
where (@value is null or column = @value) 

以下查詢是上述查詢的擴展版本。它也可以正常工作。

select * from 
table 
where ((@value is null) 
    or (@value is not null and column = @value)) 

上述2個查詢會利用索引嗎?

查詢2:下面的查詢比較列與非空@value否則將列column與它自己進行比較,它總是爲真並返回所有內容。它也可以正常工作。這個查詢會利用索引嗎?

select * from 
table 
where (column = isnull(@value, column)) 

什麼是最好的方法?

注意:如果答案因數據庫而異,我對MS-SQL感興趣。

+4

,以確定是否會有些使用索引或不就是最好的方法創建一個包含大量行的測試表,創建索引並檢查查詢的查詢計劃。 – 2010-06-24 14:42:45

+1

請注意,由於條件null = null的計算結果爲null,因此Query 2 **不會返回表中列值爲null的值,而不是true。 – 2010-06-24 14:53:41

+0

馬克,謝謝指出。該列不爲空,因此在這種情況下不會發生。 – hIpPy 2010-06-24 15:10:23

回答

1

在過去的幾天裏,這個問題的變化出現了幾次(爲什麼這些事情總是發生在團隊中?)。簡短的回答是,如果SQL Server將創建具有已知值的查詢計劃,它將使邏輯短路。所以,如果你在代碼中設置了變量的腳本,那麼我相信它應該將邏輯短路(測試是肯定的)。但是,如果它在存儲過程中,那麼SQL Server將提前創建一個查詢計劃,並且它不會知道它是否可以使查詢短路,因爲它在生成時不知道參數值查詢計劃。

無論是否短路,SQL Server應該能夠使用索引,如果這是您的查詢的唯一部分。如果變量爲NULL,那麼你可能不希望SQL Server使用索引,因爲它將是無用的。

如果你在存儲過程中,那麼你最好的選擇是在你的查詢中使用OPTION(RECOMPILE)。這將導致SQL Server每次都創建一個新的查詢計劃。這是一點點的開銷,但是收益通常超過了很多。這僅適用於SQL 2008,即使只適用於以後的某些Service Pack。之前,RECOMPILE存在一個錯誤,使其無法使用。欲瞭解更多信息,請查閱Erland Sommarskog的主題great article。具體來說,您需要查看靜態SQL部分。

1

爲了澄清一點,SQL並沒有像我們在C語言中所知道的那樣確實存在短路。什麼看起來像一個短路真的是SQL Server三元邏輯TRUE或NULL值爲TRUE

TRUE OR NULL ===> TRUE 
TRUE AND NULL ===> NULL 

如:

if 1=null or 1=1 print 'true' else print 'false' 
if 1=null and 1=1 print 'true' else print 'false'