Sql-Server

表碎片化

  • April 11, 2019

如果我執行以下操作:

SELECT dbschemas.[name] as 'Schema', 
dbtables.[name] as 'Table', 
dbindexes.[name] as 'Index',
indexstats.alloc_unit_type_desc,
indexstats.avg_fragmentation_in_percent as avg,
indexstats.page_count
FROM sys.dm_db_index_physical_stats (DB_ID('dbname'), NULL, NULL, NULL, NULL) AS indexstats
INNER JOIN sys.tables dbtables on dbtables.[object_id] = indexstats.[object_id]
INNER JOIN sys.schemas dbschemas on dbtables.[schema_id] = dbschemas.[schema_id]
INNER JOIN sys.indexes AS dbindexes ON dbindexes.[object_id] = indexstats.[object_id]
AND indexstats.index_id = dbindexes.index_id
WHERE indexstats.database_id = DB_ID('dbname')
ORDER BY indexstats.avg_fragmentation_in_percent desc

它顯示了碎片級別。然後我執行了 Ola Hallengren 的索引優化腳本,它明顯減少了索引。

如果我再次執行查詢,它現在會在沒有索引的表中顯示高碎片,例如:

Schema  Table       Index   alloc_unit_type_desc   avg                 page_cont
dbo     tablename   NULL    IN_ROW_DATA            99.4362934362934    8176

我應該擔心這些嗎?

有什麼我能做的嗎?

有什麼我應該做的嗎?

我們遇到了性能問題。我知道 2008 年並不理想,正在解決這個問題。

數據文件也顯示為 220gb,但實際使用的空間為 140gb。

Ola Hallengren 的索引優化腳本不執行堆碎片整理。

換句話說,在執行過程時不會發生表重建,這是預期的。

您可以執行ALTER TABLE dbo.tablename REBUILD; 以消除碎片。

這也會重建堆上的非聚集索引。

比重建堆表更好的選擇

您必須問問自己或應用程序團隊為什麼不能將聚集索引添加到表中。因為重建堆使用大量資源並且是臨時解決方案。

如果您添加聚集索引,該索引將包含在索引優化腳本中,並且在腳本執行時將刪除碎片。

另一種選擇是添加聚集索引,不再擔心索引碎片。


我們遇到了性能問題。我知道 2008 年並不理想,正在解決這個問題。

可能是因為堆表中的轉發記錄,但在 8167 頁我會說這不太可能。一個起點可能是查看您的伺服器上正在執行的查詢。

SP_BlitzCache可以幫助您找到性能最差的查詢。


數據文件也顯示為 220gb,但實際使用的空間為 140gb。

這應該不是問題。除了磁碟空間,你不應該太擔心。你不依賴自動增長,這是一件好事。

引用自:https://dba.stackexchange.com/questions/234551