2011-01-27 76 views
0

系統是:SQL Server 2008-R2如何評估SQL OR運算符

我有一個表,它的一列是名爲「Level」的tinyint。 等級是一個非負數。

當我這樣做:

SELECT XXXXX 
FROM YYYYY 
WHERE (------------) AND 
     (Level >= @MinLevel) AND 
     (------------) 

我得到一個正確的響應。

在嘗試優化查詢,我試圖做的:

SELECT XXXXX 
FROM YYYYY 
WHERE (------------) AND 
     ((@MinLevel = 0) OR (Level >= @MinLevel)) AND 
     (------------) 

如果請求的最低水平爲0是沒有必要的最低 級別限制添加到查詢,並通過節省對於操作比較操作(假設在無級指數)

我究竟是一個較長的查詢或至少不低於「未優化」一個較短的查詢。

任何人都可以解釋爲什麼嗎?

+0

嘗試添加`OPTION(RECOMPILE)`這有什麼區別嗎?還有`@ MinLevel`是局部變量還是參數? – 2011-01-27 11:50:18

+0

可能是因爲您試圖從dbms中優化查詢並自己完成這項工作。在大多數情況下,dbms更好。 – Femaref 2011-01-27 11:50:23

回答

2

的問題是,SQL服務器-2008-R2,所以我們贏了」不要考慮其他DBMS。

看一看這裏的一些深入的分析:http://www.sommarskog.se/dyn-search-2008.html

它討論了許多方法來進行動態搜索這是對問題有所相關。特別是這句話:

所有的@x的效果是NULL 條款是,如果輸入 參數爲NULL,則該 和條件始終爲真。 因此, 但在效果上 唯一條件是其中所述搜索參數 具有非空值。

....和性能? 很好 只要你包括查詢提示 OPTION(RECOMPILE)。

這部分Static SQL被發現,適用於SQL 2008 R2 CU1 (10.50.1702) or later

相同的優化快捷鍵(RHS評價只有當(@MinLevel = 0))適用於與OPTION(RECOMPILE)提示您的查詢。

(注意到,這已經對這個問題的評論已建議)

0

所述或條款(在幾乎任何DBMS)不是最佳的。 例如,它意味着一個索引將被忽略,這兩種情況都進行評估

直> =僅僅是一個直接比較

0

的OR手術通常索引拋出窗外。

想象一下,您有一個帶有索引ID列的表,每行計數一次。在這張表中你有100行。行1將在此列中的值1,而行100將具有100

的值現在運行此查詢: SELECT * FROM表WHERE列> = 45

此查詢具有明確的起點:45

因此,它將檢查的第一條記錄是正確的在你的表的中間,列值是50.這對於45來說太高了,但它已經消除了它的一半表不必看。然後它會查看該組中間的記錄,其值爲25.這太低了,但它又取消了一半的結果。長話短說,爲了找到第45個,它只能看6到7行。然後,它將從表格​​的每一行將您的結果集提供給表格的每一行。

現在,讓我們調整該查詢是這樣的:SELECT * FROM表WHERE列> = 45或列= 43

我們不再有一個明確的起點。數據庫無法確定一個特定的行以開始您的結果。爲了確定要返回哪些記錄,必須每行檢查以確保它符合您的要求。如果匹配,它會將該行添加到其結果中並移至下一行。