AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 4283
Accepted
Nick Chammas
Nick Chammas
Asked: 2011-08-04 10:43:53 +0800 CST2011-08-04 10:43:53 +0800 CST 2011-08-04 10:43:53 +0800 CST

我应该什么时候重建索引?

  • 772

我应该何时重建关系数据库 (SQL Server) 中的索引?

是否有定期重建索引的情况?

sql-server index-maintenance
  • 6 6 个回答
  • 92344 Views

6 个回答

  • Voted
  1. Best Answer
    Matt M
    2011-08-04T11:31:29+08:002011-08-04T11:31:29+08:00

    冒着在我的回答中过于笼统的风险,我会说您应该定期运行索引维护过程。但是,您的索引维护过程应该只重建/重组特别需要它的索引。

    这就提出了一个问题:何时需要重建或重组索引?罗兰多很好地谈到了这一点。同样,我冒着非常广泛的风险。当碎片级别对性能产生不利影响时,索引需要维护。这种程度的碎片可能会根据索引的大小和组成而有所不同。

    对于 SQL Server,我倾向于选择索引大小和索引碎片级别,此时我开始执行索引维护。如果索引包含少于 100 页,我将不进行维护。

    如果一个索引在 10% 到 30% 之间是碎片化的,我将REORGANIZE索引和UPDATE统计信息。如果索引碎片超过 30%,我将REBUILD索引 - 没有UPDATE STATISTICS,因为这是由REBUILD. 请记住,虽然重建只更新与索引直接关联的统计对象。其他列统计信息需要单独维护。

    这个答案真的只是一个很长的路要走:是的,你应该做例行的索引维护,但只在需要它的索引上。

    • 47
  2. Nick Chammas
    2011-08-04T21:56:04+08:002011-08-04T21:56:04+08:00

    我应该何时重建关系数据库(例如 SQL Server)中的索引?

    当索引因特殊事件而变得高度碎片化时,您应该重建索引。例如,您将大量数据加载到索引表中。

    是否有定期重建索引的情况?

    那么,如果您的索引由于定期活动而定期变得碎片化怎么办?您是否应该安排定期重建?他们应该多久跑一次?

    Tom Kyte在这个经典的 Ask Tom 线程中建议:

    索引重建之间的时间延迟应该大约是 FOREVER。

    ...

    不知道如何更好地说——索引想要大而肥,有额外的空间。它位于您更新的列上——将索引条目在索引中从一个位置移动到另一个位置。一天该行的代码是“A”,第二天代码是“G”,然后是“Z”,然后是“H”,依此类推。因此,该行的索引条目在索引中从一个位置移动到另一个位置。当它这样做时,它需要空间——如果没有空间,我们会将块分成两部分——并腾出空间。现在指数越来越胖了。随着时间的推移,索引的大小是您开始时的 2-3 倍,并且“一半或更多是空的”但这没关系,因为您可以移动行。现在,当我们移动行时,我们不再需要拆分块来腾出空间——房间已经可用了。

    然后你来重建或删除并重新创建索引(具有相同的效果 - 只是重建“更安全” - 不会丢失索引并且可以更快,因为索引可以通过重建扫描现有索引而不是扫描表并排序和构建新索引)。现在,所有美好的空间都消失了。我们重新开始拆分块的过程——让我们回到我们开始的地方。

    你没有节省空间。

    指数又回到了原来的样子。

    你只会浪费你的时间来重建它,导致这个恶性循环重演。

    这里的逻辑是合理的,但它偏向于读取重负载配置文件。

    “胖”索引(即一个有很多间隙的索引)确实为新的和移动的行保留了大量的空间,从而减少了页面拆分并保持您的写入速度。但是,当您从该胖索引中读取时,您将不得不读取更多页面才能获得相同的数据,因为您现在正在筛选更多的空白空间。这会减慢您的阅读速度。

    因此,在读取繁重的数据库中,您希望定期重建或重组索引。(多久和在什么条件下?Matt M 已经对这个问题有一个具体的答案。)在经历大致相同的读写活动的数据库中,或者在写入繁重的数据库中,您可能会通过重建索引来损害数据库的性能经常。

    • 21
  3. mrdenny
    2011-08-04T10:51:55+08:002011-08-04T10:51:55+08:00

    大多数人会定期重建它们,以免它们变得支离破碎。何时需要重建它们取决于它们碎片化的速度。一些索引需要经常重建,而另一些则基本上不需要。查看SQLFool放在一起的脚本,它可以为您处理大量的这些问题。

    • 11
  4. amandamaddox3
    2017-12-15T13:13:30+08:002017-12-15T13:13:30+08:00

    正如 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
    
    • 9
  5. KrishnaV
    2015-03-21T06:53:46+08:002015-03-21T06:53:46+08:00

    我应该什么时候重建索引?

    当索引碎片百分比超过 30% 时。

    是否有定期重建索引的情况?

    没有这种情况,但一般来说,每周做一次索引维护,周末是保持环境稳定的最佳做法。

    我建议使用 Ola Hallengren 的维护脚本(最佳维护脚本),根据您的环境自定义脚本并安排它们在周末运行。

    https://ola.hallengren.com/

    注意:请不要忘记在重建索引后更新统计信息,因为重建索引不会更新所有统计信息。

    • 5
  6. Greg
    2017-12-15T22:36:43+08:002017-12-15T22:36:43+08:00

    与 IT 中的大多数事情一样,这取决于。您试图通过重建索引来解决什么问题?你能证明它确实解决了问题吗?如果是这样,然后调整数字,直到找到解决问题所需的最少维护量。

    如果它不能解决问题,或者您这样做的原因只是为了安抚您监控的某些指标,因为它可能会使事情变得更好,那么您所做的就是烧毁 CPU 和 IO,并可能使您的问题变得更糟。

    有一种观点认为修复碎片不会对您的服务器产生任何影响,那么定期进行是否值得?

    https://www.brentozar.com/archive/2017/12/index-maintenance-madness/

    http://brentozar.com/go/defrag

    • 1

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    您如何显示在 Oracle 数据库上执行的 SQL?

    • 2 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    我可以查看在 SQL Server 数据库上运行的历史查询吗?

    • 6 个回答
  • Marko Smith

    如何在 PostgreSQL 中使用 currval() 来获取最后插入的 id?

    • 10 个回答
  • Marko Smith

    如何在 Mac OS X 上运行 psql?

    • 11 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Marko Smith

    将数组参数传递给存储过程

    • 12 个回答
  • Martin Hope
    Manuel Leduc PostgreSQL 多列唯一约束和 NULL 值 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler 什么时候应该将主键声明为非聚集的? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - 哪个更好作为主键? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick 如何优化大型数据库的 mysqldump? 2011-01-04 13:13:48 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve