2013-10-14 143 views
0

我有一些連接表的查詢,當我使用=運營商,而不是運營商in在where子句中像這樣我得到一個顯著的性能提升。SQL服務器

  • =運營商需要不到一秒鐘的時間。
  • in運營商需要一分鐘左右的時間。

where P.GID in (SELECT GID from [dbo].[fn_SomeFunction] (15268))

子查詢返回1周的結果在大多數情況下,只是這種變化將改善大多數情況下反而會造成一些其他情況下的錯誤。

任何想法,爲什麼這種行爲?

+0

提供的實際查詢會有所幫助。 –

+0

這是一個表值函數嗎?如果是這樣,請嘗試交叉應用它,而不是將它放在子查詢中 –

+0

如果您使用** IN **的方式發佈,那不是一個提高性能的SARGable運算符(通常** IN **不是),而** = **運算符則是。 – Question3CPO

回答

1

嘗試類似的東西,它不是測試,並可能包含一些語法錯誤。 主要想法是在臨時表變量中獲得所需的id並在連接中使用它。 希望有所幫助。

DECLARE @gids TABLE( 
GID UNIQUEIDENTIFIER NOT NULL 
) 

INSERT INTO @gids (GID) 
    SELECT 
     GID 
    FROM [dbo].[fn_SomeFunction](15268) 

SELECT * FROM SomeTable st INNER JOIN st.GID = @gids.GID 
0

如果真正代表一個功能,那就是被殺死你的執行時間。您可以通過查看執行計劃來驗證這一點。 會發生什麼情況是,在你的子查詢中,函數必須一遍又一遍地計算。如果您可以刪除該功能並替換查詢,則應該注意到有所改進。

此外,如果函數返回類型與列的類型不匹配,則需要對每個返回項目執行隱式轉換。更改函數返回類型(或列類型)以匹配也將有助於性能。

日期時間<> SMALLDATETIME例如,需要一個隱式轉換。

+0

我用實際的查詢替換了函數,但它仍然在運算符中花費一分鐘,while =運算符花費的時間不到一秒 – mmohab

+0

有沒有辦法知道它是否被一次又一次地執行? – mmohab

+0

您可以在查詢執行計劃中看到該信息(Ctrl + M並執行,您將看到底部的選項卡)。一個圖標會帶來巨大的成本。如果該項目是嵌套循環或轉換,它會一遍又一遍地運行 – orgtigger