Answers:
冒我的回答过于笼统的风险,我会说您应该定期运行索引维护过程。但是,您的索引维护过程应仅重建/重新组织特别需要它的索引。
这提出了一个问题:何时需要重建或重组索引?罗兰多很好地谈到了这一点。再次,我冒着极大的风险。当碎片级别对性能造成不利影响时,索引需要维护。碎片级别可能会根据索引的大小和组成而有所不同。
对于SQL Server,我倾向于选择索引大小和索引碎片级别,从这一点开始执行索引维护。如果索引少于100页,我将不进行维护。
如果索引的碎片在10%到30%之间,我将REORGANIZE
编制索引和UPDATE
统计信息。如果索引的碎片率超过30%,我将REBUILD
使用-否UPDATE STATISTICS
,因为这会由照顾REBUILD
。请记住,尽管重建仅更新直接与索引关联的统计对象。其他列统计信息将需要单独维护。
这个答案实际上只是一个很长的说法:是的,您应该执行例行索引维护,但只能在需要它的索引上进行。
什么时候应该在关系数据库(例如SQL Server)中重建索引?
当索引因特殊事件而变得高度分散时,您应该重建索引。例如,您将大量数据加载到索引表中。
是否需要定期重建索引?
那么,如果您的索引由于常规活动而定期变得零散怎么办?您应该安排定期重建吗?他们应该多久运行一次?
汤姆·凯特(Tom Kyte)在这个经典的《问汤姆》(Ask Tom)主题中建议:
索引重建之间的时间差应该大约永远。
...
不知道怎么说更好-索引要大而胖,并要有额外的空间。它在您更新的列上-将索引条目在索引中的不同位置移动。该行有一天的代码是“ A”,第二天的代码是“ G”,然后是“ Z”,然后是“ H”,依此类推。因此,该行的索引条目在索引中移动。这样,它需要空间-如果空间不存在,将需要将空间分成两部分-并留出空间。现在,该指数正在发胖。随着时间的推移,索引是启动时大小的2-3倍,并且是“一半或更多的空”,但这是可以的,因为您在四处移动行。现在,当我们四处移动行时,我们不再需要拆分块来腾出空间-该空间已经可用。
然后,您开始重建或删除并重新创建索引(具有相同的效果-只是重建“更安全”-不会失去索引,并且可以更快地重建索引)扫描现有索引,而不是扫描表并进行排序和构建新索引)。现在,所有的美好空间都消失了。我们重新开始重新划分区块的过程-让我们回到开始的地方。
您没有节省空间。
该索引恢复了原来的状态。
您只是在浪费时间来重新构建它,从而导致这种恶性循环不断重复。
这里的逻辑是合理的,但是它偏重于读取大量负载。
“胖”索引(即有很多空白的索引)的确确实为新行和移动行保留了足够的空间,从而减少了页面拆分并保持了写入速度。但是,当您从该胖索引中读取数据时,您将必须阅读更多的页面才能获得相同的数据,因为您现在正在筛选更多的空白空间。这会减慢您的阅读速度。
因此,在需要读取大量数据的数据库中,您希望定期重建或重新组织索引。(多长时间一次以及在什么条件下?Matt M已经对这个问题有一个具体的答案。)在经历大致相等的读写活动的数据库中,或者在大量写入的数据库中,您可能会通过重建索引来损害数据库的性能。经常。
大多数人会定期对其进行重建,以使他们永远不会分散。您何时需要重建它们取决于它们破碎的速度。一些索引将需要经常重建,而其他一些索引则基本上不需要重建。查看SQLFool放在一起的脚本,该脚本可以为您解决很多问题。
正如Matt M接受的答案中指出的那样,一条普遍的经验法则是应重建碎片超过30%的索引。
此查询将帮助您查找有多少索引碎片超过30%(当有一些索引时,应重建它们):
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
什么时候应该重建索引?
当索引碎片百分比大于30%时。
是否需要定期重建索引?
没有这种情况,但是通常,每周维护一次,在周末进行一次索引维护是保持环境稳定的最佳做法。
我建议使用Ola Hallengren的维护脚本(最佳维护脚本),根据您的环境自定义脚本,并安排它们在周末运行。
注意:重建索引后,请不要忘记更新统计信息,因为重建索引不会更新所有统计信息。
与IT中的大多数事情一样,这取决于。您正在尝试通过重建索引来解决什么问题?您能证明它确实可以解决问题吗?如果是这样,请调整数字,直到找到解决问题所需的最少维护。
如果它不能解决问题,或者您执行此操作的原因只是为了使监视的指标令人满意,因为它可能会使情况变得更好,那么您正在做的就是消耗CPU和IO,并可能使问题变得更糟。
有一个论点是,修复碎片不会对您的服务器造成任何影响,所以值得定期进行吗?
https://www.brentozar.com/archive/2017/12/index-maintenance-madness/