SQL Server 中,索引碎片(Index Fragmentation)是指索引在物理存储和逻辑顺序上的不一致,导致查询性能下降。主要有两种情况:

🔹 索引碎片的类型

  1. 逻辑碎片(Logical Fragmentation)
    • 也叫外部碎片(External Fragmentation)。
    • 页的逻辑顺序和物理顺序不一致,页在磁盘/数据文件中分散存储,影响顺序扫描性能。
    • 原因:频繁的 插入、删除、更新 导致页分裂(Page Split)。
  2. 内部碎片(Internal Fragmentation)
    • 页内存储不够紧凑,存在大量未使用空间。
    • 例如一页能存放 8 行数据,但因为删除或更新导致一页只存了 3 行。
    • 影响点:需要读取更多的页才能获取相同数量的数据。

🔹 如何检查索引碎片

可以使用 DMV sys.dm_db_index_physical_stats 查看:

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, 'LIMITED') 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
WHERE indexstats.database_id = DB_ID()
ORDER BY indexstats.avg_fragmentation_in_percent DESC;

其中:

  • avg_fragmentation_in_percent > 30%:严重碎片
  • 5% – 30%:中度碎片
  • < 5%:几乎无影响

🔹 处理方式

  1. 索引重组(Reorganize)ALTER INDEX [索引名] ON [表名] REORGANIZE;
    • 在线操作,不会阻塞。
    • 适合碎片率 5% – 30% 的情况。
    • 仅对叶子节点做整理,页会按逻辑顺序重新链接。
  2. 索引重建(Rebuild)ALTER INDEX [索引名] ON [表名] REBUILD WITH (ONLINE = ON);
    • 会删除并重新创建索引。
    • 适合碎片率 > 30% 的情况。
    • 可以选择 ONLINE = ON 来减少锁阻塞(企业版支持)。
  3. 数据库维护计划
    • 可以配置 SQL Server Agent 定期执行重组或重建操作,保证索引健康。

🔹 最佳实践

  • 定期检查:每周或每月检查索引碎片率。
  • 选择合适 Fill Factor:设置合理的填充因子(Fill Factor),避免频繁的页分裂。
  • 冷热分离:对频繁更新的表(OLTP 系统),碎片更严重,需要更频繁维护;对只读或追加式表(如日志),几乎不需要。