首先,考虑碎片是否重要很重要。
如果您的查询仅执行单行查找,则可能根本不会注意到碎片。在现代SAN上,SAN级别的缓存可能使物理IO足够快,以至于碎片无关紧要。在SSD上,由扫描碎片索引引起的随机IO模式实际上可能比未碎片化的数据具有更好的性能。
通常,人们会注意到重新建立索引可以解决性能问题。重建索引也会建立新的统计数据。实际修复可能是最新统计信息,而不是重建索引。UPDATE STATISTICS...WITH FULLSCAN
可能是解决同一性能问题的一种更便宜,更快,更不麻烦的方式。
如果您没有因碎片造成的问题,那么您可能会花费大量的时间和精力,而没有实际的收获。
其次,有两种碎片:
物理碎片。这就是大多数人想到碎片时的想法。页面混乱,需要重新排序。当扫描一个索引这种类型的碎片有时可以是一个问题。我通常注意到这对物理读取的性能影响最大。如果您正在查看的结果sys.dm_db_index_physical_stats
,则此数字为avg_fragmentation_in_percent
列。
低密度碎片化。这种碎片是由仅部分填充数据的页面引起的。您的数据密度较低,因为您的数据分布在不必要的页面上。结果,读取数据需要更多的IO,因为数据分布在不必要的页面上。这会影响逻辑和物理读取。如果您正在查看的结果sys.dm_db_index_physical_stats
,则此数字为avg_page_space_used_in_percent
列。仅在使用SAMPLED
或DETAILED
模式时填充此列。
那么您如何处理:
物理碎片:如果您只是为了追求高数字avg_fragmentation_in_percent
,请真正考虑您是否在浪费时间。确保您的实际查询效果不佳,并使用测试环境通过消除碎片来确认您要解决的问题。
您可以通过这样做解决物理碎片ALTER INDEX...REORGANIZE
。该REORGANIZE
操作是在线的,一次移动一页以将其重新组织为物理顺序。如果您在REORGANIZE
中途取消一条语句,则将保留所有已执行的工作-仅回滚当前正在移动的一页。在REORGANIZE
高度分散的大型表上执行操作可能需要更多的总事务日志空间,并且在完全恢复模式下可能会产生大量的事务日志备份。REORGANIZE
高度分散的索引所花的时间可能比REBUILD
它要长。
您经常会看到建议REBUILD
在高碎片索引上执行,而不是在REORGANIZE
-上执行,这是因为从头开始重建可能会更有效率。但是,重组可能是“更在线的”操作,有时甚至对于高度分散的索引也是首选的。
低密度碎片无法通过固定REORGANIZE
。它只能通过执行来固定ALTER INDEX...REBUILD
。通过使用做索引ONLINE=ON
,您应该能够最大程度地减少阻塞。但是,REBUILD
仍然需要花一点时间将旧索引替换为新索引。在非常繁忙的系统上,获得此独占锁定有时可能是一个问题。通过使用诸如sp_whoisactive之类的东西在重建期间检查阻塞,并查看锁和等待的详细信息,您应该能够确认是否遇到此问题。WAIT_AT_LOW_PRIORITY
如果您知道即将出现利用率低的时期,并且在活动量下降到足以获得该锁定的程度时,重新构建可以“潜入”此交换,则使用该选项可能很有用。注意长时间运行REBUILD
操作也将是长期运行的公开交易。长时间运行的开放式事务可能会遇到与事务日志使用/重用相关的问题。如果使用镜像或可用性组,则还需要考虑辅助副本上的事务日志重做。
REORGANIZE
也将减少叶子页的碎片和紧凑的空间,如REBUILD
,效率较低。您确定大尺寸是由于碎片造成的吗?填充因子是多少?