SQL Server 2008R2 中的自動更新統計資訊:儘管插入了大量行,為什麼有些統計資訊仍然過時?
在調查慢查詢期間,執行計劃似乎異常次優(一個嵌套循環執行 900 萬次查找,估計執行次數為 1)。在確認了一些確實過時的相關統計資訊後,我重新建構了統計資訊,性能問題得到了有效解決。
此數據庫啟用了自動更新統計資訊(預設情況下啟用)。我了解基於 20% + 500 行修改(更新/插入/刪除)的自動統計更新有一個門檻值。多個索引似乎已在很大程度上超出此門檻值,因此似乎存在 (A) 自動更新問題或 (B) 更新策略的內容比我在網上找到的要多文件。
我很欣賞可以設置計劃任務來更新統計資訊,如果找不到其他解決方案,這很可能是我們採取的方法,但它確實讓我們感到困惑,為什麼如此大量的修改不會觸發某些統計數據的自動更新 - 了解原因可能有助於我們決定哪些統計數據需要由計劃任務更新。
一些附加說明:
- 該問題出現在數據庫中,其中數據是通過負載測試創建的,因此在短時間內添加了大量數據,因此如果定期發生自動更新(例如,最多一天一次)那麼這可以解釋一些觀察到的行為。此外,我們的負載測試往往會給數據庫帶來很大壓力,因此我想知道 SQL 是否會在負載過重時推遲統計更新(並且隨後由於某種原因不更新統計)。
- 在嘗試使用包含連續 INSERT、SELECT 和 DELETE 語句的測試腳本重新創建此問題時,該問題並未發生。我想知道這裡的區別是否是這些語句每個都會影響每個 SQL 語句的許多行,而我們的負載測試腳本將傾向於單獨插入行。
- 有問題的數據庫設置為“簡單”恢復模式。
一些相關連結:
我也通過 microsoft connect 提出了這個問題:
2011 年 6 月 30 日更新:
在進一步調查中,我認為超出門檻值級別的過期統計資訊(例如 500 行 + 20%)是問題查詢未使用的統計資訊,因此它們可能會在執行查詢時更新這需要他們。對於查詢使用的統計資訊,這些資訊會定期更新。剩下的問題是,這些統計數據在僅進行相對較少的插入後就嚴重誤導了查詢計劃優化器(例如,在估計數量為 1 的情況下導致上述 900 萬左右的搜尋)。
我此時的預感是問題與主鍵選擇不當有關,鍵是使用 NEWID() 創建的唯一標識符,因此這會很快創建高度碎片化的索引 - 特別是作為 SQL 中的預設填充因子伺服器是 100%。我的預感是,在相對較少的行插入後,這會以某種方式導致誤導性統計數據 - 低於重新計算統計數據的門檻值。這一切都可能不是問題,因為我已經生成了大量數據而沒有部分重建索引,因此糟糕的統計數據可能是導致索引碎片非常高的結果。我認為我需要在負載測試中添加 SQL Server 維護週期,以便更好地了解真實係統在很長一段時間內的性能。
更新 2012-01-10:
另一個需要考慮的因素。SQL Server 2005 中添加了兩個跟踪標誌(並且似乎在 2008 年仍然存在),以解決與出現過時和/或誤導性統計相關的特定缺陷。有問題的標誌是:
DBCC TRACEON(2389) DBCC TRACEON(2390)
MSDN:Ian Jose 的 WebLog:Ascending Keys and Auto Quick Corrected Statistics Statistics on Ascending Columns,Fabiano Amorim
在決定啟用這些標誌時,您當然應該非常小心,因為它們可能會產生不利影響。
一些資訊,如果不是明確的答案
最近在部落格上
也有白皮書。請參閱“在 SQL Server 2008 中維護統計資訊”部分,其中有一些聽起來會影響您的情況。例子:
自動更新邏輯的一個限制是它跟踪統計中列的更改,但不跟踪謂詞中列的更改。如果過濾統計資訊的謂詞中使用的列有很多更改,請考慮使用手動更新來跟上更改。
最後還有一些設置需要檢查:如果數據庫級別的 OFF 覆蓋索引/統計級別的 ON 怎麼辦?
HTH…