在 SQL Server 中,索引碎片(Index Fragmentation)是指索引在物理存储和逻辑顺序上的不一致,导致查询性能下降。主要有两种情况:
🔹 索引碎片的类型
- 逻辑碎片(Logical Fragmentation)
- 也叫外部碎片(External Fragmentation)。
- 页的逻辑顺序和物理顺序不一致,页在磁盘/数据文件中分散存储,影响顺序扫描性能。
- 原因:频繁的 插入、删除、更新 导致页分裂(Page Split)。
- 内部碎片(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%:几乎无影响
🔹 处理方式
- 索引重组(Reorganize)
ALTER INDEX [索引名] ON [表名] REORGANIZE;
- 在线操作,不会阻塞。
- 适合碎片率 5% – 30% 的情况。
- 仅对叶子节点做整理,页会按逻辑顺序重新链接。
- 索引重建(Rebuild)
ALTER INDEX [索引名] ON [表名] REBUILD WITH (ONLINE = ON);
- 会删除并重新创建索引。
- 适合碎片率 > 30% 的情况。
- 可以选择 ONLINE = ON 来减少锁阻塞(企业版支持)。
- 数据库维护计划
- 可以配置 SQL Server Agent 定期执行重组或重建操作,保证索引健康。
🔹 最佳实践
- 定期检查:每周或每月检查索引碎片率。
- 选择合适 Fill Factor:设置合理的填充因子(Fill Factor),避免频繁的页分裂。
- 冷热分离:对频繁更新的表(OLTP 系统),碎片更严重,需要更频繁维护;对只读或追加式表(如日志),几乎不需要。