【问题标题】:How often should the indexes be rebuilt in our SQL Server database?在我们的 SQL Server 数据库中应该多久重建一次索引?
【发布时间】:2011-01-17 13:05:39
【问题描述】:

目前我们的数据库大小为 10 GB,并且每月增长约 3 GB。我经常听说应该不时重建索引,以提高查询执行时间。那么在给定的场景中,我应该多久重建一次索引呢?

【问题讨论】:

    标签: sql-server indexing sql-server-2005 maintenance-plan


    【解决方案1】:

    人们普遍认为,一旦索引碎片达到 5 个以上(有时为 10%),您应该重新组织(“碎片整理”)您的索引,并且当它超过 30%(至少这是我听说过很多地方都提倡的数字)。

    Michelle Ufford(又名“SQL Fool”)有一个 automated index defrag script,它使用这些确切的限制来决定何时重组或重建索引。

    另请参阅Brad McGehee's tips on rebuild indexes,了解有关如何处理索引重建的一些好的想法和技巧。


    我在这里使用这个脚本(不记得我是从什么时候得到这个的——不管是谁:非常感谢!非常有用的东西)来显示给定数据库中所有索引的索引碎片:

    SELECT 
        t.NAME 'Table name',
        i.NAME 'Index name',
        ips.index_type_desc,
        ips.alloc_unit_type_desc,
        ips.index_depth,
        ips.index_level,
        ips.avg_fragmentation_in_percent,
        ips.fragment_count,
        ips.avg_fragment_size_in_pages,
        ips.page_count,
        ips.avg_page_space_used_in_percent,
        ips.record_count,
        ips.ghost_record_count,
        ips.Version_ghost_record_count,
        ips.min_record_size_in_bytes,
        ips.max_record_size_in_bytes,
        ips.avg_record_size_in_bytes,
        ips.forwarded_record_count
    FROM 
        sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'DETAILED') ips
    INNER JOIN  
        sys.tables t ON ips.OBJECT_ID = t.Object_ID
    INNER JOIN  
        sys.indexes i ON ips.index_id = i.index_id AND ips.OBJECT_ID = i.object_id
    WHERE
        AVG_FRAGMENTATION_IN_PERCENT > 0.0
    ORDER BY
        AVG_FRAGMENTATION_IN_PERCENT, fragment_count
        
    

    【讨论】:

    【解决方案2】:

    “当你需要时”和“当你可以时”!

    例如...

    • 首先测试碎片并决定是什么都不做,重组还是重建。 例如SQL Fool's script does this@minFragmentation@rebuildThreshold 参数

    • 比如说,每天做统计,但在周末做索引。您的维护时段是多少?

    【讨论】:

      【解决方案3】:

      您应该经常重建索引,以免索引退化对生产造成不利影响。我知道这似乎含糊不清,但是所有数据库都是不同的,并且以不同的方式使用。您只需要定期重建/碎片整理会导致写入操作(插入/更新)的索引 - 您的静态或大部分只读表将不需要太多重新索引。

      您将需要使用dbcc showcontig([Table]) 检查索引的碎片级别,确定它们的碎片频率以及碎片的实际级别。

      使用dbcc dbreindex([Table])在索引变得过于碎片化(超过20%-30%左右)时完全重建索​​引,但如果您找不到足够大的停机时间窗口并且碎片级别相对较低(1%-25% ),您应该使用dbcc indexdefrag([Database], [Table], [Index]) 以“在线”方式对索引进行碎片整理。另请注意,您可以停止索引碎片整理操作并在以后重新启动它,而不会丢失任何工作。

      保持数据库及其索引“协调一致”需要进行一些监控才能真正了解何时以及重新索引的内容。

      【讨论】:

      【解决方案4】:

      鉴于您的数据库的大小,您可以轻松地每月重建一次索引。但是随着大小的增加,比如大约 500 GB,您可以每月执行两次。

      【讨论】:

      • 当然,取决于未结交易的数量、它们的类型和生命周期。这可能是一个非常活跃的 10GB 数据库。
      【解决方案5】:

      Bacon Bits comment Ola Hallengren's SQL Server Maintenance Solution 中提到过 SQL Server 2008、SQL Server 2008 R2、SQL Server 2012、SQL Server 2014、SQL Server 2016、SQL Server 2017、SQL Server 2019、Azure SQL 数据库和 Azure 支持 IndexOptimize SQL 数据库托管实例。
      它在https://github.com/olahallengren/sql-server-maintenance-solution 上有 2K 颗星。

      Michelle Ufford(又名“SQL Fool”)的automated index defrag script,在the accepted answer 中提出建议,在概念上似乎与 Ola Hallengren 的 SQL Server 维护解决方案相同,但最新版本是 2011 年。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-04
        • 2011-01-04
        • 2011-05-12
        • 1970-01-01
        相关资源
        最近更新 更多