1

這是一個可能的this question重複,儘管我認爲我的示例更深入一些,我希望得到更明確的答案。 我試圖理解爲什麼運行與option(recompile)簡單的查詢表現更好。使用選項(重新編譯)運行SQL查詢總是更快

DECLARE @p9 nvarchar(4000) 
SET @p9=N'Alex%' 

SELECT ContactId as CandidateId 
FROM Candidate 
      WHERE 
       (
        @p9 IS NULL 
        OR 
        Forename LIKE @p9 
        OR 
        PreferredName LIKE @p9 
        OR 
        Surname LIKE @p9 
       ) 

當沒有option(recompile)運行(不管多少次,我運行它)

(1166 row(s) affected) 
Table 'Candidate'. Scan count 5, logical reads 9762, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 

Execution plan with no recompile option specified

非常相同的查詢,但option(recompile)添加到底

(1166 row(s) affected) 
Table 'Candidate'. Scan count 3, logical reads 18, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 

Execution plan with no recompile option specified

如果我不在查詢中使用變量,而是使用常量,那麼一切都很好。我認爲這是與參數嗅探有關,但問題是爲什麼? 還有什麼是離開option(recompile)生產代碼的缺點?

我也做了一些診斷測試,從應用程序內部運行查詢,並且似乎與option(recompile)它總是更快的結果。

更新:運行exec sp_updatestats沒有效果,並選擇與option(recompile)仍然執行更好。

謝謝你的時間。

+0

你打算在你的問題中增加更多信息嗎? – 2014-09-25 06:37:25

+0

你覺得我缺乏我的問題嗎?架構? – 2014-09-25 07:20:28

+0

@MitchWheat,我的主要問題是爲什麼'選項(重新編譯)'有這種影響 – 2014-09-25 07:45:30

回答

1

Option(recompile)基於當前的統計數據生成新計劃,代價是編制新計劃。如果您的統計數據是最新的,然後是100次中的99次,那麼您將得到一個最佳計劃(而不是緩存的查詢計劃,可能不適合您傳入的特定參數集,而不是計劃緩存的時間。這被稱爲參數嗅探)

「另外,對於 生產代碼,離開選項(重新編譯)會有什麼缺點?」

這是罰款報告查詢,但將是每秒運行多次查詢一個壞主意,因爲每次重新編譯該計劃的成本將可能超過實際執行查詢的成本!

另外,請注意使用Option(recompile)的缺點是該程序不會顯示在相關的DMV中。

+0

表的統計信息是在運行查詢前更新的 – 2014-09-22 09:51:05

+0

你如何保證? – 2014-09-22 09:51:23

+0

那麼,在運行查詢之前,我在表上運行了更新統計信息(還重建了所有索引等),並且在沒有其他人使用它的情況下處理隔離的數據庫。 – 2014-09-22 09:53:59