MySQL不直接提供索引碎片率,但可通过SHOW TABLE STATUS查Data_free估算;若free_mb超size_mb的20%~30%且存在大量DELETE/UPDATE,则建议OPTIMIZE TABLE或ALTER TABLE … REBUILD优化。
怎么查 MySQL 表的索引碎片率
MySQL 本身不直接暴露“碎片率”数值,但可以通过 INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS 和 INFORMATION_SCHEMA.INNODB_SYS_INDEXES 配合估算。更实用的是查 DATA_FREE 和页利用率:
- 对 InnoDB 表,执行
SHOW TABLE STATUS LIKE 'your_table_name',关注Data_free字段(单位字节)——它表示已分配但未使用的空间,值越大越可能有碎片 - 用
SELECT table_name, round(((data_length + index_length) / 1024 / 1024), 2) AS size_mb, round((data_free / 1024 / 1024), 2) AS free_mb FROM information_schema.tables WHERE table_schema = 'your_db' AND table_name = 'your_table'; - 若
free_mb超过size_mb的 20%~30%,且表长期有大量 DELETE/UPDATE,就值得优化
OPTIMIZE TABLE 能不能重建索引
对 InnoDB 表,OPTIMIZE TABLE 实际上等价于 ALTER TABLE ... FORCE(MySQL 5.6+),会重建整个表并重新组织聚簇索引和二级索引,同时更新统计信息。
- 它会锁表(在可重复读隔离级别下是 ALGORITHM=COPY,全表拷贝;8.0+ 支持 INPLACE,但仍需排他 MDL 锁)
- 不适用于只读从库或高负载主库,容易触发超时或阻塞写入
- 执行后
Data_free通常归零或显著下降,但不会改变索引结构逻辑(比如不会合并单列索引为联合索引)
ALTER TABLE … REBUILD 和 ANALYZE TABLE 的区别
ALTER TABLE t REBUILD(MySQL 8.0.23+)仅重组织物理存储,不重建索引定义;而 ANALYZE TABLE 只更新索引统计信息(用于优化器选执行计划),完全不碰数据页。