將數據庫移動到 SQL Server 2014 後的性能問題
我收到了一個以前在 SQL Server 2008R2 上但只是放在 SQL Server 2014 實例上的數據庫。自 2014 年以來,沒有在數據庫上執行任何類型的維護任務(例如重建索引、更新統計資訊等)。
一旦我們執行更新統計資訊作為我們按固定時間表進行的定期維護的一部分,某些查詢的性能就會受到巨大影響,以至於某些選擇語句似乎永遠不會完成。
查詢中有一些 CASE…WHEN 語句,但我不希望會有這樣的性能影響。有人對可能導致此類問題的原因有任何想法嗎?
我嘗試將兼容性級別更新為 120,因為當數據庫第一次進入時它是 100,但是這對性能沒有任何影響。
包含執行計劃的連結:
好的,此時我會考慮“手動”替換統計數據以渡過難關。我自己沒有這樣做,但它應該在理論上有效……
您可以確認這將按如下方式工作:
- 將升級前的數據庫恢復到您的 LIVE 系統並確認該數據庫中的查詢速度很快,完成後刪除該數據庫。(這個測試是為了消除任何額外的環境差異作為原因。如果查詢很慢,那麼這個建議的其餘部分可能沒有用。)
1a。將升級前的數據庫恢復到您的測試系統並確認查詢速度很快。2. 更新統計資訊,確認查詢慢(當然幾分鐘後取消)
將 compat 設置為 120 並確認查詢仍然很慢
將 compat 設置回 100 並確認查詢仍然很慢
5.恢復另一個升級前數據庫的副本(我將這裡稱為Rest2,更早的稱為Rest1)
6. 使用https://thomaslarock.com/2015/07/how-to-recreate-sql-server-statistics-in-a-different-environment/中 的技術從 Rest2 中提取所有涉及問題的表的統計資訊查詢(或所有表,如果這更簡單)
- 將統計資訊應用於 Rest1,並查看查詢現在是否很快(您可能需要先 dbcc freeproccache)。
如果它有效,那麼將統計資訊應用於您的實時數據庫幾乎肯定是安全的——只需確保您只編寫了統計資訊腳本。並將其兼容級別設置為 100。然後您應該會看到查詢執行得很快(儘管您可能需要先 dbcc freeproccache ——但請考慮對實時性能的可能影響)。
請注意,我在這裡假設(根據您的原始文章)您沒有打開統計資訊自動更新,並且您的數據變化得足夠慢,以至於您的舊統計資訊會一直執行,直到您弄清楚如何讓您的工作負載與 compat 120 和/ 或更新的統計資訊(此時您也可以對兩者進行排序)。
一些想法:
您是否使用了與 2008R2 不同的方法來更新統計資訊?不同的方法會產生非常不同的結果。
數據庫在 2008R2 上時設置的兼容性級別是多少?它可能低於 100,因為 100 是 2014 年的最小值,並且您可能已受到早期統計數據重新生成更改的影響。
為了在調查時恢復以前的行為的最佳機率,首先將兼容性級別設置回 100,然後清除查詢記憶體。(DBCC freeproccache——當第一次重新執行查詢時,請注意重新編譯可能對實時系統造成的 CPU 影響。)然後嘗試將統計資訊恢復到與之前狀態相似的狀態(這也應該在適當的時候觸發重新編譯)。
(抱歉,我還不能添加評論,請不要投反對票。)
更新:
為了澄清我為什麼說您應該將兼容性級別設置回 100:這是因為級別 120 將啟用對 SQL 2014 引入的基數估計器的廣泛更改,但級別 100 將保持 SQL 2008R2 中的內容。
但我很好奇您發布的兩個計劃之間的查詢執行時間差異,以及每個計劃是在哪個系統上生成的。因為這兩個計劃在整個過程中都有非常相似的估計行和實際行(這表明統計數據不是問題),而且我可以看到的計劃差異似乎不會導致執行時間的巨大差異。
在更新統計資訊之前,您絕對確定這些查詢實際上執行沒有問題嗎?如果不是,您的 SQL 2014 伺服器是否可能有一個非常慢的 tempdb 位置,它正在殺死臨時結果集的寫入?
您發布的查詢是否由應用程序完全按照發布的方式執行,或者它們是否作為儲存過程的一部分執行(這會對生成的計劃產生重大影響)?如果是儲存過程的一部分,也許您只是有參數嗅探問題,如果您將選項(重新編譯)添加到您已確定為有問題的大型複雜查詢的末尾,這將得到緩解 - 以一些 CPU 和響應時間為代價和其他缺點。https://www.brentozar.com/archive/2013/12/recompile-hints-and-execution-plan-caching/是開始了解細微差別的好地方。
請務必發布您的最終解決方案,因為這是一個有趣的案例。