Sql-Server
sys.dm_db_index_physical_stats 非常慢
我有一個大約 4.5TB 的數據庫,因為我們在一個表(按月分區)上進行了並行插入(以減少每日載入時間),因此該表上的聚集索引往往是嚴重碎片化的。當我在此表上從 sys.dm_db_index_physical_stats (Limited) 中進行選擇時,它需要很長時間(> 4-5 小時)。有沒有更快更好的方法來檢查這張表的分區上的碎片級別,目前這花費的時間是完全不能接受的。
不要為整個數據庫執行 DMV,而是為特定的表或索引執行它。由於數據庫規模龐大,它必然需要時間。
您必須閱讀Paul Randal 的解釋,了解為什麼這個 DMV 可能需要更多時間。
DMV 的想法是顯示索引的物理屬性(以及堆的特殊情況) - 為此,它必須掃描包含索引的頁面,併計算統計資訊。許多 DMV 支持所謂的謂詞下推,這意味著如果您指定 WHERE 子句,DMV 在準備資訊時會將其考慮在內。這個DMV沒有。如果你只詢問數據庫中邏輯碎片 > 30% 的索引,它會掃描所有索引,然後只告訴你那些符合你條件的索引。它必須這樣做,因為它無法知道哪些符合你的標準,直到它分析它們——所以不能支持謂詞下推。
您是否嘗試過用於索引重建的Ola Hallengren解決方案。
如他的文章中所述,您可以嘗試多種模式。但正如你所說的有限也需要 4-5 個小時,我想這就是 DMV 是什麼。它實際上很慢,甚至 MS 也相信它。
索引重建被視為維護活動,應在伺服器負載相對較少或在維護視窗期間進行。
我今天看了這篇文章後做了一個測試。我在 SQL Server 2019 上有一個非常零散的表。
表本身是3GB,索引是6GB。我只用查詢檢查了 1 個表:
SELECT OBJECT_NAME(ips.OBJECT_ID), i.NAME, ips.index_id, index_type_desc, avg_fragmentation_in_percent, avg_page_space_used_in_percent, page_count FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'SAMPLED') ips INNER JOIN sys.indexes i ON(ips.object_id = i.object_id) AND (ips.index_id = i.index_id) WHERE OBJECT_NAME(ips.OBJECT_ID) = 'MyTableName' ORDER BY avg_fragmentation_in_percent DESC;
在沒有壓力的測試數據庫上花費了01:18 小時。
所以,是的,有時它可能非常慢