具有慢速索引假離線(急切假離線)和舊伺服器使用索引的新 SQL Server
所以昨天我發布了這個問題,關於我們已經升級
SQL Server 2008
到SQL Server 2017
並且我們遇到了一些性能問題。我得到了嘗試更新適用於一個數據庫但不適用於其他數據庫的統計資訊的答案。我應該將兼容性級別設置為 2008 年到 2017 年嗎?目前,兼容性級別保持在 100 (SQL Server 2008)。
舊伺服器是物理伺服器,新伺服器是 VM (Hyper-V)。
升級後的執行計劃看起來與舊版本不同,似乎使用 Index Spool(Eager Spool)而不是使用 index。這意味著執行時間從舊伺服器上的 3 秒變為新伺服器上的 1 分 50 秒。
我注意到與沒有 Eager Spool 的數據庫具有相同查詢的唯一不同之處在於表行較少,它
13.000.000
是非工作70.000
行與使用正確執行計劃工作的行。以下計劃是匿名的,但我希望有足夠的資訊。
我試過了
- 更新統計資訊
cost threshold for parallelism
相應地改變max degree of parallelism
。- 仔細檢查索引是否和以前一樣。
- 我看過了
READ_COMMITTED_SNAPSHOT
。- 我檢查了 NUMA 配置。
另一個問題是等待類型很高
LCK_M_IS, CXPACKET, LCK_M_X, ASYNC_IO_COMPLETION, LCK_M_IX, PAGELATCH_EX, BACKBUFFER, TRACEWRITE.
我開始沒有想法了。
最大記憶體設置為為作業系統留出 4GB,我昨天注意到主機上的電源計劃設置為平衡但將其更改為高性能,但仍然存在同樣的問題。
收到更新統計資訊的建議:
似乎已經在其中一個數據庫上工作,但是我在所有其他數據庫上仍然有問題。
舊伺服器是具有 8 個核心和 32GB RAM 的物理伺服器。新伺服器是在 Hyper-V 上執行的虛擬機,具有 4 個核心和 64GB 記憶體。
新伺服器中的 RAM 量可能會增加一倍,這會導致查詢優化器選擇性能比預期差的計劃。
您可以嘗試使用
DBCC OPTIMIZER_WHATIF
1來查看如果您有 20 個核心且只有 32 GB 的 RAM 會發生什麼,就像舊系統一樣。我寫了一篇博文,展示了它在sqlserverscience.com上的工作原理。要查看 32GB RAM 對計劃選擇的影響,可以使用以下命令:
dbcc optimizer_whatif ('MemoryMBs', 32768);
您需要從計劃記憶體中逐出查詢計劃,或強制使用或強制編譯新計劃,
WITH RECOMPILE
以OPTION (RECOMPILE)
查看這是否會導致 SQL Server 選擇“更好”的計劃。如果您在使用後看到更好的計劃
dbcc optimizer_whatif
,您可能會考慮重構查詢以允許優化器做出更好的選擇,或者您可以創建計劃指南。您可能對這個問題感興趣,以及關於在具有不同資源的兩台伺服器上執行計劃的差異的答案。
供未來訪問者參考:問題指出大多數數據庫都保持在兼容級別 100;這排除了與 SQL Server 2014+ 中基數估計器更改相關的一系列潛在問題。
1 - 請注意,這是一個不受支持的 DBCC 命令,只能用於測試目的。
升級 SQL Server 時,有許多任務需要完成,以確保“順利”(er) 過渡。
我使用的列表可以在這裡找到。此列表包括執行
CHECKDB
、檢查兼容性級別、刷新視圖和更新統計資訊等任務。就您而言,陳舊的統計數據似乎是您的問題。這樣做的結果是基數估計器無法對預測數據分佈和返回的行進行準確的估計,從而產生不同的且可能不是最佳的執行計劃。
根據更新的問題進行編輯
您還提到了更新兼容性級別。上述連結提供了有關如何以及為什麼應該或可以調整兼容性級別的資訊。更改它的主要原因之一是 v12 (SQL Server 2014) 對基數估計器進行了重大升級。確定這是否會對您產生影響的最佳方法是對其進行測試,最好在升級上線之前進行。這可以幫助您在升級後生成類似的執行計劃。