2011-07-05 63 views
0

問題涉及到性能和最佳實踐。 (SQL Server 2008中存儲過程)sql server 2008存儲了多個或條件的proc優化最佳實踐

如果存儲過程包含這樣

result = select count(*) from tableA where (some condition1) 

if (result) -- meaning we got something from above query 
    return result 
else 
    result = select count(*) from tableA where (some other condition2) 
and so on until 
result = select count(*) from tableA where (some other conditionN) 

代碼是更好地把所有的條件,在一個大的這樣的查詢

resultn = select count(*) from tableA 
    where (condition1 or condition1 or... conditionN) 

請問表每種情況都要進行掃描,或者無論有多少條件都要進行一次表掃描。什麼是處理這種邏輯的優雅方式。謝謝

+0

這看起來不像是有效的t-SQL代碼 - 我知道它是僞代碼,但是有些(count)應該與其他(count)?另外,你的兩段代碼看起來並不像邏輯上等價。 –

+0

湯姆。做出了改變。 thx – Gullu

回答

1

您的兩個代碼塊在邏輯上不相同。我將假設IF(result)確實意味着IF(@result > 0)。在這種情況下,將返回您找到的第一個非零計數。在您的第二個代碼塊中,您將實際獲得所有條件的總計。

在您的第二個代碼塊中,SQL Server只能爲查詢選擇一個查詢計劃。如果您在所有列上都有索引,它仍然只能使用其中的一個。我不認爲認爲它會使用每個查詢條件的索引進行並行處理。雖然我沒有專門測試過,所以也許有人可以糾正我,如果我錯了。您可以通過在存儲過程中使用WITH RECOMPILE指令來緩解一些問題。這在SQL 2005中有一些錯誤,但由於你在SQL 2008上,你應該沒問題。

在您的第一個代碼塊中,SQL Server可以爲每個查詢分別提供查詢計劃。

在任何情況下,哪一個實際上是最好將取決於很多因素。您最好的選擇是與測試數據並排測試,這些測試數據非常接近地模擬您的實際生產數據。

另外,不要忘記代碼的可維護性和可讀性。如果這是不經常運行的代碼,或者性能差異足夠小,那麼使用最易於維護和理解的代碼可能會更好,尤其是在您有很多條件或可能經常更改的情況下。

最後,請問這些條件是否依賴於存儲過程的參數?這些參數中的一些常常會被忽略,這意味着條件不相關?如果是這樣,那麼你應該仔細閱讀Erland Sommarskog的article on dynamic search conditions。在一個客戶端,我發現動態SQL是這種情況下性能最高的方法,但是當涉及到安全性時,必須採取很多措施來使此代碼保持密封狀態。

+0

湯姆,thx爲詳細的迴應。雖然我不明白,但我有指點我需要做我的功課。 – Gullu

1

最好在IN子句中加入不同的條件,因爲它只會做一次計劃,然後檢查多個條件,但是如果你要執行seperaly,它將不得不每次執行計劃。

+0

thx。我想我需要閱讀SQL Server計劃。不清楚爲什麼它沒有爲個人條件查詢和我所有條件下的一個大查詢創建一個計劃。 – Gullu

1

不可能說全面掃描是否會發生,取決於數據的基數,以及是否有合適的索引。

假設每個選擇意願的全掃描...

,你的WHERE子句是不同的,你將不得不將這一邏輯在選擇使用CASE WHEN

見:http://msdn.microsoft.com/en-us/library/aa258235(v=sql.80).aspx

,那麼你將需要一個條件塊來返回正確的值。

好處是這隻會完整掃描一次。

+0

除了計劃你的迴應告訴我,我也需要閱讀基數。 thx爲那個鏈接 – Gullu