不知道從哪一個開始這一個 - 不知道是否問題是我愚弄查詢優化器,或者如果它是內在的當涉及到空值時指標的工作方式。SQL Server查詢優化:其中(Col = @ Col或@ Col = Null)
一個編碼約定,我跟着是編寫像這樣的存儲過程:當你想要一個存儲過程來
declare procedure SomeProc
@ID int = null
as
select
st.ID,st.Col1,st.Col2
from
SomeTable st
where
(st.ID = @ID or @ID is null) --works, but very slow (relatively)
這不是說簡單的測試用例是非常有用的,當然,但在其他情況下非常有用在滿足某些條件的整個表或行上進行操作。然而,更大的表使用時...大約提升3至5慢於如果我換成where子句這是相當緩慢:
where
st.ID = @ID --3-5x faster than first example
我甚至用事實與更換空更不解-1讓我幾乎相同的速度「固定」 WHERE子句上面:
declare procedure SomeProc
@ID int = -1
as
select
st.ID,st.Col1,st.Col2
from
SomeTable st
where
(st.ID = @ID or @ID=-1) --much better... but why?
顯然,這是一個的把事情古怪,但爲什麼,到底空?從審查執行計劃來看,我的答案並不明確。這是我多年來在SQL Server的各種數據庫,表和版本上注意到的,所以我不認爲這是我當前環境的一個怪癖。 我通過將默認參數值從null切換到-1來解決問題;我的問題是爲什麼這個工程。
注
- SomeTable.ID被索引
- 這可能與(或可能,其實是)一個參數嗅探問題 Parameter Sniffing (or Spoofing) in SQL Server 不管它的價值,我已經 測試幾乎完全與 「exec SomeProc」後每個 編輯/重新編譯的過程,即與 的可選參數省略。
感謝偉大的答覆。我懷疑這是最重要的。我很無知OR的代價如何。最後,在提示之後,爲了便於閱讀,我使用存儲過程頂部的SET @ ID = ISNULL(@ ID,-1)。 (實際存儲的過程相當長,我不想在裏面埋藏「默認」)再次感謝。 –