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 版本的功能差异
相关推荐
科技块儿1 小时前
常见IP归属地数据库对比
网络·数据库·tcp/ip
m***92381 小时前
【MySQL】C# 连接MySQL
数据库·mysql·c#
u***28471 小时前
SpringBoot集成Flink-CDC,实现对数据库数据的监听
数据库·spring boot·flink
m***11901 小时前
Ubuntu 系统下安装 Nginx
数据库·nginx·ubuntu
e***98571 小时前
Window下Redis的安装和部署详细图文教程(Redis的安装和可视化工具的使用)
数据库·redis·缓存
xingyue_S1 小时前
MySQL 数据库(一) -- 初体验
数据库·mysql·oracle
X***C8621 小时前
【Oracle11g SQL详解】UPDATE 和 DELETE 操作的正确使用
数据库·sql
爬山算法1 小时前
Redis(156)Redis的延迟问题如何解决?
数据库·redis·缓存
v***91301 小时前
Windows版Redis本地后台启动
数据库·windows·redis