SELECT DB_NAME() AS DBName,
OBJECT_NAME(ind.object_id) AS TableName,
ind.name AS IndexName,
indexstats.index_type_desc AS IndexType,
indexstats.avg_fragmentation_in_percent,
indexstats.fragment_count,
indexstats.avg_fragment_size_in_pages,
SUM(p.rows) AS Rows
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, NULL) AS indexstats
INNER JOIN sys.indexes AS ind ON ( ind.object_id = indexstats.object_id
AND ind.index_id = indexstats.index_id)
INNER JOIN sys.partitions AS p ON ( ind.object_id = p.object_id
AND ind.index_id = p.index_id)
WHERE indexstats.avg_fragmentation_in_percent > 30
GROUP BY
OBJECT_NAME(ind.object_id),
ind.name,
indexstats.index_type_desc,
indexstats.avg_fragmentation_in_percent,
indexstats.fragment_count,
indexstats.avg_fragment_size_in_pages
ORDER BY indexstats.avg_fragmentation_in_percent DESC
冒着在我的回答中过于笼统的风险,我会说您应该定期运行索引维护过程。但是,您的索引维护过程应该只重建/重组特别需要它的索引。
这就提出了一个问题:何时需要重建或重组索引?罗兰多很好地谈到了这一点。同样,我冒着非常广泛的风险。当碎片级别对性能产生不利影响时,索引需要维护。这种程度的碎片可能会根据索引的大小和组成而有所不同。
对于 SQL Server,我倾向于选择索引大小和索引碎片级别,此时我开始执行索引维护。如果索引包含少于 100 页,我将不进行维护。
如果一个索引在 10% 到 30% 之间是碎片化的,我将
REORGANIZE
索引和UPDATE
统计信息。如果索引碎片超过 30%,我将REBUILD
索引 - 没有UPDATE STATISTICS
,因为这是由REBUILD
. 请记住,虽然重建只更新与索引直接关联的统计对象。其他列统计信息需要单独维护。这个答案真的只是一个很长的路要走:是的,你应该做例行的索引维护,但只在需要它的索引上。
当索引因特殊事件而变得高度碎片化时,您应该重建索引。例如,您将大量数据加载到索引表中。
那么,如果您的索引由于定期活动而定期变得碎片化怎么办?您是否应该安排定期重建?他们应该多久跑一次?
Tom Kyte在这个经典的 Ask Tom 线程中建议:
这里的逻辑是合理的,但它偏向于读取重负载配置文件。
“胖”索引(即一个有很多间隙的索引)确实为新的和移动的行保留了大量的空间,从而减少了页面拆分并保持您的写入速度。但是,当您从该胖索引中读取时,您将不得不读取更多页面才能获得相同的数据,因为您现在正在筛选更多的空白空间。这会减慢您的阅读速度。
因此,在读取繁重的数据库中,您希望定期重建或重组索引。(多久和在什么条件下?Matt M 已经对这个问题有一个具体的答案。)在经历大致相同的读写活动的数据库中,或者在写入繁重的数据库中,您可能会通过重建索引来损害数据库的性能经常。
大多数人会定期重建它们,以免它们变得支离破碎。何时需要重建它们取决于它们碎片化的速度。一些索引需要经常重建,而另一些则基本上不需要。查看SQLFool放在一起的脚本,它可以为您处理大量的这些问题。
正如 Matt M 接受的答案中所指出的,一个常见的经验法则是应该重建碎片超过 30% 的索引。
此查询将帮助您找到有多少索引超过 30% 碎片(当您有一些时,您应该重建它们):
当索引碎片百分比超过 30% 时。
没有这种情况,但一般来说,每周做一次索引维护,周末是保持环境稳定的最佳做法。
我建议使用 Ola Hallengren 的维护脚本(最佳维护脚本),根据您的环境自定义脚本并安排它们在周末运行。
https://ola.hallengren.com/
注意:请不要忘记在重建索引后更新统计信息,因为重建索引不会更新所有统计信息。
与 IT 中的大多数事情一样,这取决于。您试图通过重建索引来解决什么问题?你能证明它确实解决了问题吗?如果是这样,然后调整数字,直到找到解决问题所需的最少维护量。
如果它不能解决问题,或者您这样做的原因只是为了安抚您监控的某些指标,因为它可能会使事情变得更好,那么您所做的就是烧毁 CPU 和 IO,并可能使您的问题变得更糟。
有一种观点认为修复碎片不会对您的服务器产生任何影响,那么定期进行是否值得?
https://www.brentozar.com/archive/2017/12/index-maintenance-madness/
http://brentozar.com/go/defrag