如此頻繁地更新統計資訊是否正常?
我有一個儲存過程,它處理來自源表的數據,並且全天執行多次(大約 20,000 次執行)。
我相信它有時會因為參數嗅探而阻塞,並且我一直在更新過程中相關表(8 個表)的統計資訊以解決此問題。
當它被阻塞時,積壓的未處理數據就會積壓(我可以監控這些數據。)
一旦我更新了統計數據,積壓的工作就會立即被清除。
我發現自己每天更新統計數據大約 10 次(幾乎每小時一次)。這看起來很正常,還是我應該尋求解決更大的問題?
有多種方法可以解決參數嗅探問題。
如果您每天更新統計數據 10 次,尤其是如果這會導致性能問題,那麼我會考慮其他選項。
很有可能更新統計資訊並不能解決您的參數嗅探問題。統計資訊的更新會導致計劃從記憶體中刷新(這可能正在解決您的問題)。僅從記憶體中刷新該計劃可能也可以正常工作,而無需重建統計資訊;)
如果我是你,我會從一開始就找出哪些參數集導致 SQL 採用錯誤的執行計劃。一旦你有了這個,你就可以開始尋找修復它的方法。
您可以使用 QueryStore 來解決此問題,例如強制 SQL 始終使用“好”的執行計劃。
有時,一個好的索引也可以解決參數嗅探問題(這可能導致 SQL 建構一個不同的執行計劃,無論參數是什麼都好)
您可能會遇到這樣一種情況,即(可能是預設的)採樣百分比不足以使統計數據在較長時間內有用。
UPDATE STATISTICS
您可以通過以下查詢快速檢查最後一條語句中使用的採樣率:SELECT OBJECT_SCHEMA_NAME(st.object_id) + '.' + OBJECT_NAME(st.object_id) AS TableName , col.name AS ColumnName , st.name AS StatsName , sp.last_updated , sp.rows_sampled , sp.rows , (1.0*sp.rows_sampled)/(1.0*sp.rows) AS sample_pct FROM sys.stats st INNER JOIN sys.stats_columns st_col ON st.object_id = st_col.object_id AND st.stats_id = st_col.stats_id INNER JOIN sys.columns col ON st_col.object_id = col.object_id AND st_col.column_id = col.column_id CROSS APPLY sys.dm_db_stats_properties (st.object_id, st.stats_id) sp --WHERE OBJECT_SCHEMA_NAME(st.object_id) + '.' + OBJECT_NAME(st.object_id) = 'dbo.Mytable' -- <-- uncomment to filter for a specific table ORDER BY 1, 2
如果您過濾導致問題的表並且您發現採樣率很低,您可能需要嘗試增加採樣率以查看統計數據是否在更長的時間內保持相關性。你甚至可能會發現
FULLSCAN
s 是必要的。下面是幾個例子,展示了我所說的關於提高采樣率的內容:-- reference 20 percent of the column table when building the stat UPDATE STATISTICS dbo.MyTable myTableStatName WITH SAMPLE 20 PERCENT -- or - -- reference all the column data when building the stat UPDATE STATISTICS dbo.MyTable myTableStatName WITH FULLSCAN
值得注意的是,如果您確實發現提高采樣率可以提高統計數據的壽命,並且您使用的是 SQL Server 2016 SP1 CU4(或 SQL Server 2017 CU1)或更高版本,則
PERSIST_SAMPLE_PERCENT
該UPDATE STATISTICS
命令會包含一個新關鍵字。此關鍵字強製針對所述統計數據執行的任何自動更新統計資訊使用您手動指定的任何樣本百分比。如果不包含此關鍵字,則在自動更新統計資訊執行期間將使用預設採樣,如果您需要更高的採樣百分比,這可能會成為一個令人頭疼的問題。Tiger 團隊發布了一篇關於該主題的精彩部落格文章,如果您想了解有關此新關鍵字的更深入資訊,我建議您查看。
感謝@RandiVertongen 的評論,正如Erin Stellato 的部落格文章中所述,在為初始測試
FULLSCAN
選擇更大百分比之前嘗試 a 可能會更有意義。SAMPLE