为什么不重建页数小于1000的索引?


17

我使用Ola Hallengrens脚本进行索引维护。在此之前,我使用以下查询来查看哪些索引最分散:

SELECT dbschemas.[name] as 'Schema',
dbtables.[name] as 'Table',
dbindexes.[name] as 'Index',
indexstats.avg_fragmentation_in_percent,
indexstats.page_count
FROM sys.dm_db_index_physical_stats (DB_ID(), 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
ORDER BY indexstats.avg_fragmentation_in_percent desc

在我的情况下,avg_fragmentation 对于15个索引而言超过70%,对于28个索引而言超过30%

因此,我使用Ola Hallengren的解决方案重建了每个索引。当我再次运行查询时,结果如下:

碎片超过70%12个索引,超过30%15个索引。

我认为,原因是因为page_count仍然非常分散的每个索引的均小于1000。例如,具有page_count 967 的索引之一的 碎片百分比为98,98%!对我来说,似乎值得重建该索引!我这样做了,之后,碎片是0%。另外,a page_count值为132 的指数从95%变为0%

所以,我的问题是,为什么不重建那些索引会有什么原因?原因之一可能是重建需要花费时间和资源,但是由于索引较小,这是否意味着花费相对较少的资源并且无论如何仍然要进行重建?

这个站点上有多个相关问题,但是所有这些问题都回答了为什么索引不进行碎片整理,或者如果索引很小并且您不对它们进行碎片整理,索引是否仍然有用,而在这里,该语句确实减少了碎片,问题是,为什么不这样做呢?


小索引可能会缓存在内存中。始终不会引起IO的索引不会从碎片整理中受益。此1000页计数规则是一种启发式方法。
usr 2015年

Answers:


20

关于最小页数的指导有些随意。减少碎片的最大好处是:

  1. 它可以提高范围扫描的预读性能;和
  2. 它可以提高页面密度(每页的行数)

顾名思义,这两个因素对于小索引而言都不那么重要。

重建小索引的反驳本质上是:

“为什么要打扰?您还有其他重要的事情要担心吗?”。

也就是说,重建/重组不是免费的。在某些情况下(例如,出于多种可能的原因(例如镜像,可用性组,复制...)跨WAN运送/复制日志)可能需要避免额外的工作和日志生成。另外,除非(或者即使在某些情况下)在线重建,否则重建可能会通过锁定影响其他并发进程。最后,对于小索引,由于来自混合扩展区的分配,重建甚至都无法减少碎片(除非您正在启用跟踪标志1118的情况下运行)。

如果您仍然更高兴地重建这些小索引,并且不介意后果,那么请务必更改@PageCountLevel传递给Ola过程的参数值。

有关所有详细信息,请参见Paul Randal的PASS电视录像,内容为“索引碎片 ”。

您可能还想看Brent Ozar谈论为什么索引碎片在SQL Server中无关紧要。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.