在 SQL Server 2012 中重建/重组索引时要考虑的因素

Tha*_*ddy 7 index sql-server sql-server-2012

我对根据sys.dm_db_index_physical_statsdm 函数返回的 avg_fragmentation_in_percent 选择索引重组/重建索引感到困惑。

Msdn 说:

在此处输入图片说明

而且,avg_fragmentation_in_percentvalue 表示索引中存在的逻辑碎片百分比(这是索引的叶页中乱序页的百分比)。

Reorganize of index将始终修复页面的物理顺序。所以即使 avg_fragmentation_in_percent 大于 30% 我也可以考虑重新组织索引。它将减少索引中的碎片百分比。

请看下面的例子

SELECT 
    database_id, object_id,
    avg_fragmentation_in_percent,
    avg_page_space_used_in_percent,
    page_count,
    avg_fragment_size_in_pages
FROM
    SYS.Dm_db_index_physical_stats (Db_id('BPIGTN_GAL_APP_TST'), Object_id('NM_PPA_PROJECTION_MASTER'), NULL, NULL, 'SAMPLED') 
Run Code Online (Sandbox Code Playgroud)

结果

 Database_id Object_id  avg_fragmentation_in_percent  avg_page_space_used_in_percent    page_count  avg_fragment_size_in_pages
    37       913490383        99.36                           60.15                      314           1.003
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我们可以看到 99% 的平均值,fragmentation这意味着索引有更多的逻辑碎片(页面无序更多)。

所以我要重新组织我们在上图中看到的索引。

请查看下面的示例以进一步了解。

ALTER INDEX PK_NM_PPA_PROJECTION_MASTER_PROJECTION_DETAILS_SID_RS_CONTRACT_SID ON NM_PPA_PROJECTION_MASTER REORGANIZE
GO

SELECT database_id,
       object_id,
       avg_fragmentation_in_percent,
       avg_page_space_used_in_percent,
       page_count,
       avg_fragment_size_in_pages
FROM   SYS.Dm_db_index_physical_stats (Db_id('BPIGTN_GAL_APP_TST'), Object_id('NM_PPA_PROJECTION_MASTER'), NULL, NULL, 'SAMPLED') 
Run Code Online (Sandbox Code Playgroud)

结果

Database_id Object_id   avg_fragmentation_in_percent    avg_page_space_used_in_percent  page_count  avg_fragment_size_in_pages
37           913490383           4.18                                       98.91           191       9.55
Run Code Online (Sandbox Code Playgroud)

上面,我们有re-organized索引,因此在重组后average_fragmentation减少到4 percent并且使用的空间从60 percent to 98 percent.

Msdn 建议为Reorganize/Rebuild索引考虑 Avg_Fragmentation_in_percent 值。

但是 Avg_Fragmentation_In_Percent 值仅表示逻辑碎片而不是索引中未使用的空间量。

所以,我对在重新组织/重新构建索引之间进行选择有点困惑。

我们是否可以同时考虑 Avg_fragmentation_in_percent 和 Avg_page_space_used_in_percent 值来选择重建索引或重组索引?

任何人请建议我选择重建或重新组织索引时要考虑的确切参数?

Eri*_*ing 8

我将转向与其他答案不同的方向并问:在您的碎片整理程序运行了几分钟或几小时,并使用了各种资源(CPU、内存、磁盘,可能是 tempdb)之后,您如何量化并将时间和服务器资源花费在碎片整理索引上与您从这样做中获得的任何改进进行比较?

我意识到这并没有回答你的问题,但我希望你仔细考虑你在做什么,而不是让自己紧张起来,你的服务器都因为一个非问题而受到打击。

SQL Server 用户对索引碎片有一种奇怪的痴迷(相信我,我曾经也有这种痴迷)。它通常基于 15 年前 Microsoft 的建议以及问答论坛(包括这个论坛)上的许多歇斯底里的回答。

人们已经将你提到的数字(重组 5%,重建 30%)永远充满了宗教热情。所以他们一直在做。我也看到它会导致各种各样的问题。阻塞和死锁、损坏、生产工作负载中断(长时间运行的维护),最糟糕的是:在排除更重要的维护(如DBCC CHECKDB.

一个好的东西,索引重建做的是更新的统计数据,其中(大大简化)通常会给出优化它的工作与数据更好的信息,以及(再一次,大大简化了)可以追逐错误的执行计划从缓存中。

人们还会在维护计划中做适得其反的事情,例如重建所有索引、重新组织所有索引,然后更新统计信息。我意识到这可能不是你,只是为了完整性而添加它。

除了重建或重组的碎片百分比之外,还有更多的考虑因素:

  • 查询甚至使用这个索引吗?
  • 我真的想重组和 LOB 压缩 50+ GB 的索引(单线程,ew)吗?
  • 我是否使用标准版重建离线并可能导致阻塞?

有关一些背景知识,请查看此处博客文章。全面披露; 这是我工作的公司,尽管我以外的人已经写了很多关于它的文章。甚至还有在那里后约当索引碎片的事情。

很长一段时间以来,其他数据库平台都有关于这个主题的更好的建议。

编辑:在一百万年中永远不会出现索引碎片的最佳方法:将所有数据缓存在 RAM 中。