一、索引碎片管理策略
碎片率阈值与处理方法
|---------|----------------------------|------------|
| 碎片率范围 | 推荐操作 | 特点 |
| 10%-30% | ALTER INDEX ... REORGANIZE | 在线整理,低资源消耗 |
| >30% | ALTER INDEX ... REBUILD | 离线重建或在线重建 |
二、ALTER INDEX ... REORGANIZE 完整语法
基本语法
-- 重新组织单个索引
ALTER INDEX [索引名称] ON [表名] REORGANIZE;
-- 重新组织表的所有索引
ALTER INDEX ALL ON [表名] REORGANIZE;
-- 带LOB压缩选项的重新组织
ALTER INDEX [索引名称] ON [表名]
REORGANIZE WITH (LOB_COMPACTION = ON);
语法说明
- REORGANIZE:重新组织索引的叶级别页,使物理顺序与逻辑顺序一致
- LOB_COMPACTION = ON:压缩大对象 (LOB) 数据类型的列(默认开启)
- 在线操作:始终在线,不会阻塞查询和更新操作
- 资源消耗:低,适合在业务高峰期执行
适用场景
- 索引碎片率在 10%-30% 之间
- 需要低资源消耗的维护操作
- 索引频繁被访问但碎片未达重建阈值
三、ALTER INDEX ... REBUILD 完整语法
基本语法
-- 重建单个索引(离线)
ALTER INDEX [索引名称] ON [表名] REBUILD;
-- 重建表的所有索引
ALTER INDEX ALL ON [表名] REBUILD;
-- 在线重建(企业版支持)
ALTER INDEX [索引名称] ON [表名]
REBUILD WITH (ONLINE = ON);
-- 带填充因子的重建
ALTER INDEX [索引名称] ON [表名]
REBUILD WITH (FILLFACTOR = 80);
-- 完整参数示例
ALTER INDEX [索引名称] ON [表名]
REBUILD WITH (
ONLINE = ON,
FILLFACTOR = 85,
SORT_IN_TEMPDB = ON,
MAXDOP = 4
);
主要参数说明
|----------------|----------------|------------------|
| 参数 | 说明 | 选项 |
| ONLINE | 是否在线重建 | ON/OFF(企业版支持 ON) |
| FILLFACTOR | 填充因子 | 1-100 |
| SORT_IN_TEMPDB | 是否在 tempdb 中排序 | ON/OFF |
| MAXDOP | 最大并行度 | 1 - 服务器 CPU 核心数 |
| RESUMABLE | 是否支持可恢复操作 | ON/OFF |
在线重建注意事项
-- 低优先级锁等待(企业版)
ALTER INDEX [索引名称] ON [表名]
REBUILD WITH (
ONLINE = ON (
WAIT_AT_LOW_PRIORITY (
MAX_DURATION = 10 MINUTES,
ABORT_AFTER_WAIT = SELF
)
)
);
四、索引碎片分析查询
完整查询语句
SELECT
OBJECT_NAME(ips.object_id) AS 表名,
i.name AS 索引名,
ips.index_type_desc AS 索引类型,
ips.avg_fragmentation_in_percent AS 碎片率,
ips.page_count AS 索引页数,
ips.avg_page_space_used_in_percent AS 页面使用率,
CASE
WHEN ips.avg_fragmentation_in_percent > 30 THEN '需要REBUILD'
WHEN ips.avg_fragmentation_in_percent > 10 THEN '需要REORGANIZE'
ELSE '无需处理'
END AS 建议操作
FROM
sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'DETAILED') ips
JOIN
sys.indexes i ON ips.object_id = i.object_id AND ips.index_id = i.index_id
WHERE
ips.avg_fragmentation_in_percent > 10 -- 碎片率>10%需关注
AND ips.page_count > 100 -- 页数>100才值得优化
AND i.type_desc IN ('CLUSTERED', 'NONCLUSTERED') -- 只考虑行存储索引
ORDER BY
ips.avg_fragmentation_in_percent DESC;
五、自动化索引维护脚本
自动根据碎片率执行相应操作
DECLARE @SQL NVARCHAR(MAX) = '';
SELECT @SQL += '
ALTER INDEX ' + QUOTENAME(i.name) + ' ON ' + QUOTENAME(OBJECT_SCHEMA_NAME(i.object_id)) + '.' + QUOTENAME(OBJECT_NAME(i.object_id)) +
CASE
WHEN ips.avg_fragmentation_in_percent > 30 THEN ' REBUILD WITH (ONLINE = ON);'
ELSE ' REORGANIZE;'
END
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'SAMPLED') ips
JOIN sys.indexes i ON ips.object_id = i.object_id AND ips.index_id = i.index_id
WHERE
ips.avg_fragmentation_in_percent > 10
AND ips.page_count > 100
AND i.type_desc IN ('CLUSTERED', 'NONCLUSTERED')
AND i.is_disabled = 0
AND i.is_hypothetical = 0;
PRINT @SQL;
-- EXEC sp_executesql @SQL;
六、最佳实践
1. 维护窗口选择
- REORGANIZE:可在业务高峰期执行
- REBUILD:建议在业务低峰期执行,特别是离线重建
- ONLINE = ON:企业版可在白天执行,但仍会有性能影响
2. 资源监控
-- 监控索引维护进度
SELECT
session_id,
command,
percent_complete,
estimated_completion_time,
cpu_time,
reads,
writes
FROM sys.dm_exec_requests
WHERE command LIKE '%INDEX%';
3. 版本兼容性
|-----------------------|--------|-------|
| 版本 | 在线重建支持 | 可恢复操作 |
| SQL Server Standard | 不支持 | 不支持 |
| SQL Server Enterprise | 支持 | 支持 |
| Azure SQL Database | 支持 | 支持 |
4. 统计信息更新
-- 重建索引后更新统计信息
UPDATE STATISTICS [表名];
-- 自动更新统计信息
ALTER DATABASE [数据库名] SET AUTO_UPDATE_STATISTICS ON;
七、常见问题解决方案
1. 索引维护阻塞业务
-- 使用低优先级锁
ALTER INDEX [索引名称] ON [表名]
REBUILD WITH (
ONLINE = ON (
WAIT_AT_LOW_PRIORITY (
MAX_DURATION = 5 MINUTES,
ABORT_AFTER_WAIT = SELF
)
)
);
2. 大表索引维护
-- 分批处理大表
ALTER INDEX [索引名称] ON [表名]
REBUILD WITH (
RESUMABLE = ON,
MAX_DURATION = 60 MINUTES
);
3. 监控索引使用情况
-- 检查未使用的索引
SELECT
OBJECT_NAME(ius.object_id) AS 表名,
i.name AS 索引名,
i.type_desc AS 索引类型,
ius.user_seeks + ius.user_scans + ius.user_lookups AS 总使用次数
FROM sys.dm_db_index_usage_stats ius
JOIN sys.indexes i ON ius.object_id = i.object_id AND ius.index_id = i.index_id
WHERE
ius.database_id = DB_ID()
AND i.is_primary_key = 0
AND i.is_unique_constraint = 0
ORDER BY 总使用次数 ASC;
总结
- REORGANIZE:适合轻度碎片,在线操作,低资源消耗
- REBUILD:适合重度碎片,可选择在线或离线,效果更彻底
- 自动化:建议创建维护计划定期执行索引维护
- 监控:维护过程中监控资源使用情况
- 版本:注意不同 SQL Server 版本的功能差异