索引碎片率过高时应分程度处理:<5%忽略,5%–30%建议重组,>30%应重建;sql server查sys.dm_db_index_physical_stats,mysql用data_free/(data_length+index_length)>30%判定。

索引碎片率过高时,核心应对思路是“分程度处理”:轻度碎片优先重组,重度碎片必须重建,同时兼顾锁影响和资源开销。
怎么判断碎片是否真高?
不能只看感觉,得用数据说话:
- SQL Server:运行 sys.dm_db_index_physical_stats,重点看 avg_fragmentation_in_percent 字段
- MySQL:查 SHOW TABLE STATUS,计算 Data_free / (Data_length + Index_length),结果超 30% 就算高
- 通用阈值参考: 忽略;5%–30% 建议重组;>30% 应重建
碎片高了该选重建还是重组?
关键看代价和效果的平衡:
- 重组(REORGANIZE):在线进行、低资源、适合日常维护。它整理页顺序、压缩空隙,但不回收全部空间,对严重分裂无效
- 重建(REBUILD):彻底新建索引结构,消除所有碎片、更新统计信息、回收空间。但默认会锁表(SQL Server Standard 版),Enterprise 版可用 ONLINE = ON 缓解
- 注意:MySQL 的 OPTIMIZE TABLE 本质是重建,InnoDB 下等价于 ALTER TABLE ... FORCE,MyISAM 则全程锁表
重建操作要避开哪些坑?
重建不是点一下就完事,几个硬性细节必须提前确认:
- 预留空间:重建过程需额外磁盘空间,建议留出原索引大小的 1.5 倍
- 主键重建要谨慎:InnoDB 中重建主键会连带重建所有二级索引,耗时翻倍
- 别在从库乱执行:MySQL 备库上直接跑 OPTIMIZE TABLE 可能中断复制
- 填充因子别忽略:SQL Server 重建时加 FILLFACTOR=80,可为后续更新预留空间,延缓新碎片生成
怎么让维护更省心?
靠人盯容易漏,自动化才是常态:
- 写脚本定期扫描:比如 MySQL 每周查 Data_free > 100MB 的表,SQL Server 查 avg_fragmentation_in_percent > 30 的索引
- 绑定业务低峰期:重建类操作尽量安排在凌晨或周末,避免冲击线上请求
- 搭配统计信息更新:重建后顺手执行 UPDATE STATISTICS 或确保 AUTO_UPDATE_STATISTICS 开启,防止优化器“看走眼”










