作为一名 SQL Server DBA,我有定期重建/重组索引的维护工作。最近,我问自己有关 SQL Server 中表碎片的问题。然后我阅读了有关堆表及其碎片的文章。我们不断地以各种方式检查 SQL 服务器的状态,我想知道添加对表碎片的检查是否有用。
我正在考虑开发类似的东西:“他们是集群索引吗?” 是 -> 什么都不做,否 -> 所以检查:
percentage of fragmentation > x%
numbers of forward pointing > x
numbers of rows > x
如果 x > 某些值则发出警报。
您如何看待设置这种支票,有用与否?
堆表的碎片整理是否会减少磁盘上数据库文件的物理大小?
编辑 :
我最终使用这段代码来检测需要重建的堆表:
SELECT Database_id, Object_name([object_id]) as TableName, Index_type_desc,
Avg_fragmentation_in_percent, rowmodctr, forwarded_record_count
From sys.dm_db_index_physical_stats(db_id(),object_id(''),null,null,'detailed') AS SDDIPS
Inner join sys.sysindexes AS SI on SDDIPS.[object_id] = SI.id
AND SDDIPS.index_id = SI.indid
--Inner join sysobjects AS SO on SI.id = SO.id
Where index_level = 0 AND index_type_desc = 'HEAP' AND Avg_fragmentation_in_percent > 40
AND rowmodctr > 100 AND forwarded_record_count > 1000
但是它运行了很长一段时间并且性能像PLE崩溃
我建议,与其“自己动手”,不如实施 Ola Hallengren 的索引维护脚本,这样可以节省大量时间和精力。
https://ola.hallengren.com/sql-server-index-and-statistics-maintenance.html
并且,查看 Brent Ozar 对 Ola 剧本的调整
https://www.brentozar.com/archive/2014/12/tweaking-defaults-ola-hallengrens-maintenance-scripts/
不,他们不会减少文件的物理大小。我们所说的碎片化
logical fragmentation
不是物理上的。根据 BOL,堆的碎片定义为在This SE thread中阅读有关堆碎片的更多信息。我已经解释了堆碎片的含义。
碎片的概念实际上并不适合堆,它们是一堆未排序的页面。处理堆的最佳建议是在其上创建聚集索引。另请注意,当您重建堆时,您也会重建所有非聚集索引,因此要小心,因为这将生成大量 I/O 和事务日志。可能存在您需要重建堆以摆脱转发指针的情况,在这种情况下您当然可以,但请留意正在重建的 NCI。
我不认为当碎片超过索引的特定限制时收到警报是个好主意。只需定义一个每周或每周两次重建索引的计划就足够了。您已经拥有 Ola Hallengren 脚本供您使用。