【问题标题】:Index Maintenance索引维护
【发布时间】:2009-06-04 04:06:58
【问题描述】:

什么是索引维护,我该怎么做?我必须多久做一次? 有什么好处? 这与经常修改的事务表有关;所有 DML 操作都将在该表上运行。

【问题讨论】:

    标签: sql sql-server database tsql


    【解决方案1】:

    我赞同乔纳森所说的一切——除了索引维护的频率。

    好吧,如果您碰巧有一个设计不佳的索引(例如 GUID 键上的聚簇索引),您实际上可能需要至少每晚(甚至在白天)都这样做。

    作为一般经验法则:如果您的索引碎片低于 5%,则一切正常。如果您有 5% 到大约 5% 的碎片。 30%,你应该进行索引重组:

    ALTER INDEX (your index name) ON (your table name) REORGANIZE
    

    如果你的索引有超过 30% 的索引碎片,你需要完全重建它:

    ALTER INDEX (your index name) ON (your table name) REBUILD
    

    重建索引可能会造成破坏 - 尝试在非工作时间进行,例如晚上。

    为了确定索引碎片,您可以使用这个 DMV 查询:

    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
    

    Michelle Ufford 有一个很棒的自动 index defrag script - 强烈推荐!或者,您应该考虑设置可以运行的 SQL Server maintenance plans,例如每天晚上清理你的索引。

    马克

    【讨论】:

    • 谢谢,我第一次创建索引时,会不会没有I/O操作?另一个关于大小的问题,索引的大小会随着数据/事务而增长,一段时间后我删除并重新创建相同的索引会减小大小和 I/O 操作
    • 哦,当然——创建索引会导致潜在的大量 I/O 操作!索引的大小取决于表中的行数——当你删除很多行时,重建索引可能会稍微减小它的大小,因为可以回收以前被删除行使用的空间——但是每个行的行数将需要表乘以索引中的字节数(索引字段的总和) - 那里没有魔法。
    • 我应该查看 avg_fragmentation_in_percent 关于您的 5 30 呢?重建它们?
    • 是的,完全正确 - 这是您的索引的平均碎片。 5以下可以,5-30建议重组,30及以上重建。
    • 此查询中索引名称为 NULL 的行是什么,它们被列为 index_type_desc="HEAP"。我无法为它们运行给定的 alter index 命令。忽略它们?
    【解决方案2】:

    一般来说,DBMS 会自动处理索引以使其仍然有效。但是,有了足够的插入、删除和更新操作,可以想象索引会有提升的空间。也就是说,如果删除并重新创建索引,则生成的索引将比修改后的索引更小且更有效。而且,最终,较小的索引意味着更少的 I/O 操作,而 I/O 操作比计算要昂贵得多。

    可能有一些我不知道的特定于 SQL Server 的答案,但是:

    • 索引维护是一个使索引性能更好的过程。
    • 进行索引维护的一种方法是删除并重建索引。
    • 另一种方法可能是更改表,从而必须重建索引(也许是集群)。
    • 您可能不需要经常这样做,但这主要取决于 MS SQL Server 的质量及其处理索引的方式。我希望这至少是足够的。如果您有方便的停机时间,也许每月一次。否则,很少甚至根本没有。
    • 好处是索引使用的空间更少,使用索引的性能更好。

    【讨论】:

    • 谢谢,我第一次创建索引时,会不会没有I/O操作?另一个关于大小的问题,索引的大小会随着数据/事务而增长,一段时间后我删除并重新创建相同的索引会减小大小和 I/O 操作
    • 创建索引时如果表有1000万条记录,就会有I/O;如果它有 0 条记录,则几乎没有 I/O。当您删除一些记录并添加其他记录并使记录总数保持大致恒定时,索引会发生什么,但通常情况下,它会缓慢增长。有些模式比其他模式更糟糕。例如,如果您有一个单调递增的标识列,并且总是在低端删除并在高端添加,它会破坏索引结构的平衡。但我不是 MS SQL Server 专家 - 见证我对频率想法的分歧。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    • 2019-08-17
    • 2011-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多