生產中的查詢慢、執行計劃錯誤或索引錯誤?
我剛剛通過刪除索引並重新創建它來解決生產性能問題。我懷疑刪除索引也會刪除使用它的執行計劃,其中一個恰好是壞的。
支持不良執行計劃的論據:
- 在刪除索引之前,我查看了給定表上統計資訊的最後更新日期,它們是最新的。
- 我的 DBA 實施了Hallengren 的索引和統計維護解決方案
- 慢查詢是
sp_executesql
使用日期參數執行的選擇語句。執行相同的 select 語句sp_executesql
速度很快,但也沒有使用相同的執行計劃。反對糟糕的執行計劃的論點:
- 在刪除索引之前,我們非常瘋狂地執行了禁止
dbcc freeproccache
清除任何不良計劃,但這並沒有解決或改變性能問題。筆記:
- 慢查詢恰好使用按日期索引的表。但是,每個日期的記錄數量存在很大差異。換句話說,任何給定的日期範圍從幾條記錄到超過 10 萬條記錄,而且非常隨機。
- 數據庫在兼容級別 140 (SQL Server 2017) 下執行
問題的根源是糟糕的計劃還是過時的索引?
如果這是一個糟糕的計劃,那麼為什麼
dbcc freeproccache
不努力擺脫它呢?編輯 :
據我所知,這看起來很像一個糟糕的計劃,但不知何故
dbcc freeproccache
沒有奏效。所以,我被蒙在鼓裡,對整個情況感到困惑。
這是您描述的事件的時間表,以及我對您的錯誤計劃的可能原因的評論。
- 您會收到以前速度較慢的慢查詢的警報
糟糕的時候,我同情!
- 你發瘋了,執行“禁止的 dbcc freeproccache”,但它沒有幫助
通常,如果問題是參數嗅探,清除記憶體可以解決此類問題。
- 您刪除並重新創建了錯誤計劃正在使用的非聚集索引。現在你的問題解決了
糟糕計劃的另一個原因是糟糕的統計數據。如果問題是錯誤的統計資訊,那麼清除過程記憶體只會導致再次生成相同的錯誤執行計劃(基於錯誤的統計資訊)。
在列上創建索引會在該列上創建新的統計資訊
WITH FULLSCAN
:通過掃描表或索引視圖中的所有行來計算統計資訊。
這些通常是最好的統計數據,因為它們包含最全面的數據視圖。
隨著表中的行被更改/添加/刪除,統計資訊可以隨時間自動更新。SQL Server 將根據表的大小使用不同的“採樣百分比”。從同一個文件頁面:
對於大多數工作負載,不需要完全掃描,預設採樣就足夠了。但是,某些對廣泛變化的數據分佈敏感的工作負載可能需要增加樣本量,甚至需要進行全面掃描。
聽起來發生的事情是:
- 為該索引執行了自動統計更新,採樣率低或有其他問題
- 這觸發了新執行計劃的創建,而該計劃很糟糕
- 您重新創建了索引,它再次產生了良好的統計數據
您提到您正在使用 Ola 的索引和統計資訊維護解決方案。您可能希望為此表/索引添加一個特殊情況以使用 更新統計資訊
FULLSCAN
,因為聽起來該表的數據已經傾斜到足以保證這一點。如果你想避免掃描整個表(我不知道它有多大),你可以嘗試不同的樣本百分比(從 100 開始,然後下降 5% 或 10%,直到你得到糟糕的計劃)。
查看您提供的執行計劃(謝謝!),您可以看到我的理論的證據。這是壞計劃的索引:
<StatisticsInfo Database="[BDM]" Schema="[dbo]" Table=" [SubTypeInstanceProcessAdvancements]" Statistics="[AsOfDate]" ModificationCount="288" SamplingPercent="23.4265" LastUpdate="2019-08-15T22:00:09.91" />
這是一個好的計劃:
<StatisticsInfo Database="[BDM]" Schema="[dbo]" Table=" [SubTypeInstanceProcessAdvancements]" Statistics="[AsOfDate]" ModificationCount="0" SamplingPercent="100" LastUpdate="2019-08-16T13:50:10.43" />
壞計劃的樣本百分比為
23.4265
,而好的計劃的統計數據抽樣率為 100%(因為重新創建了索引)。
為什麼不兼得?具有錯誤統計資訊的陳舊索引可能會導致生成錯誤的計劃。