我意識到線程是舊的,但這裏有一些額外的細節可能有助於作出適當的決定。有多種解決方案:
1)
SELECT ...
FROM ...
WHERE
(T.memberType = @memberType OR @memberType = -1)
AND (T.color = @color OR @color = -1)
AND (T.preference = @preference OR @preference = -1)
AND (T.groupNumber = @groupNumber OR @groupNumber = -1)
AND (T.departmentNumber = @departmentNumber OR @departmentNumber = -1)
2)
SELECT ...
FROM ...
WHERE
(T.memberType = @memberType OR @memberType IS NULL)
AND (T.color = @color OR @color IS NULL)
AND (T.preference = @preference OR @preference IS NULL)
AND (T.groupNumber = @groupNumber OR @groupNumber IS NULL)
AND (T.departmentNumber = @departmentNumber OR @departmentNumber IS NULL)
3)動態生成的DML和使用EXECUTE語句
4)動態生成的DML和使用sp_executesql的
選項1和2幾乎是一樣的......我會傾向於使用IS NULL而不是-1,但是與大多數情況一樣,這取決於情況。這些選項的缺點之一是存儲過程的第一次執行將產生一個查詢計劃,這個查詢計劃將在隨後的所有調用中重用...隨着參數值的變化(具體而言,您想忽略哪些),最初的查詢計劃可能不再是最佳計劃......要解決此問題,請使用WITH RECOMPILE選項(注意每次調用該過程時都會重新編譯該過程)。
隨着向表中添加更多數據和/或將更多條件添加到WHERE子句中,選項3和4的性能會更好。但是,這些選項需要更多努力來編寫存儲過程,並需要對輸入參數進行更多驗證,以最大限度地減少潛在的SQL注入漏洞。選項4比選項3更好,從某種意義上講更簡單一些,因爲動態生成的SQL包含參數名稱,從而導致更有效的查詢計劃重用。動態生成的SQL的另一個缺點是調用存儲過程的用戶必須擁有對基礎表/視圖的所有必要權限,除非該過程是使用WITH EXECUTE AS ...子句定義的。
最後,我通常使用動態生成的SQL和sp_executesql來產生性能最好的查詢。
這比使用'COALESCE'(對於NULL情況下)更快嗎? – crush 2016-05-09 21:00:08