SQL Server 索引维护完整指南

一、索引碎片管理策略

碎片率阈值与处理方法

|---------|----------------------------|------------|
| 碎片率范围 | 推荐操作 | 特点 |
| 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 版本的功能差异
相关推荐
科技小花2 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸2 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain2 小时前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希3 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神3 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员3 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java3 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿4 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb
不知名的老吴4 小时前
Redis的延迟瓶颈:TCP栈开销无法避免
数据库·redis·缓存
YOU OU4 小时前
三大范式和E-R图
数据库