隨時間變化的一致查詢性能
我們正在針對包含大量數據的 SQL Server 數據庫執行密集的應用程序負載(每秒數千次操作)。一些表有數十億行,其中一些有很多插入和更新。
數據庫性能一般都還可以,但我們會定期遇到查詢性能問題;以前執行良好的相當簡單的查詢可能會突然花費 10-100 倍的時間。
這似乎與表/索引統計資訊和查詢優化器有關 - 大多數情況下更新統計資訊會解決問題,然後再次更新統計資訊會使情況變得更糟(重新執行統計資訊更新通常會解決問題最終)。
似乎正在發生的事情是優化器決定對某些查詢使用客觀錯誤的索引;突然之間,在使用了正確的數天和數週之後。
我的問題是:為什麼會發生這種情況,我們能做些什麼呢?
這個數據庫已經執行了多年,負載基本相同,查詢幾乎相同,更新量也相同。對於 99.995% 的查詢,應該沒有理由隨著時間的推移決定不同的索引策略,而不管輸入是什麼(而且 - 實際上 - 這樣做會明顯地完全破壞查詢性能)。
如上所述,按計劃自動更新統計數據通常會產生可怕的問題——如果統計數據樣本出現偏差(這似乎發生在至少 5% 的時間),我們最終會陷入痛苦的世界。
有沒有辦法告訴 SQL Server(在某些表上)統計直方圖和密度不會隨時間變化,所以請繼續使用相同的查詢計劃來處理涉及該表的查詢?如果不是,我們如何確保隨著時間的推移統計更新的可預測結果(避免上面描述的傾斜統計問題)?
沒有儲存過程。我們確實可以控制 SQL,因此它可能會被更改,但它有很多程式碼,所以如果我們不得不更改每個查詢(例如添加一個附加子句),那將是不幸的。
一個後續問題:參數嗅探似乎只與儲存過程相關,對嗎?
我建議你首先確定是它的統計數據還是它的參數嗅探傷害了你。
不管以上如何,我建議您閱讀Erland關於該主題的文章。
該怎麼辦很難說。我們不知道是統計數據還是嗅探。
但可能添加
OPTIMIZE FOR
可能是“解決方案”。它比RECOMPILE
您不必在每次執行時都受到計劃生產的影響而便宜。它為您提供了可預測性。當然,這假設您沒有統計數據差異如此之大的情況,因此由於統計原因,相同的參數輸入會產生不同的計劃。嘗試確定一個查詢。查看您是否有一個或多個查詢計劃。用
OPTIMIZE FOR
和/或測試RECOMPILE
。您擁有的數據庫規模的一個“全域”選項是禁用數據庫的參數嗅探。這意味著優化器會優化,因為它不知道該值。Erland 的文章中的所有這些以及更多內容。參數嗅探不僅適用於儲存過程。它也適用於參數化 SQL(通常使用 執行
sp_executesql
),如今這可能比儲存過程更常見。