MySQL中的REORG命令并非一个独立的内置命令,而是指通过一系列操作实现表重组(Table Reorganization)的过程,主要用于优化表空间、消除碎片、提升查询性能,在MySQL中,表碎片主要源于频繁的DML操作(INSERT、UPDATE、DELETE),这些操作会导致数据页和索引页出现不连续的空间,进而降低I/O效率,重组表的核心目标是回收未使用的空间、重新组织数据物理存储,并优化索引结构。

重组表的实现方式
MySQL没有直接名为REORG
的命令,但可以通过以下方法实现类似功能:
使用ALTER TABLE
重建表
这是最常用的方法,通过ENGINE
选项触发表的重建,适用于所有存储引擎(如InnoDB、MyISAM),语法如下:
ALTER TABLE table_name ENGINE = InnoDB;
执行过程:
- 创建一个与原表结构相同的新表。
- 将原表数据逐行插入新表(过程中会锁定表,影响并发)。
- 删除原表并重命名新表。
- 重建所有索引。
优点:能有效消除碎片,优化索引和数据存储。 缺点:大表操作耗时较长,期间会阻塞写操作。

使用pt-online-schema-change
(Percona工具)
对于高并发环境,可使用Percona Toolkit中的pt-online-schema-change
工具,它通过在线方式(Online DDL)实现表重组,避免长时间锁表,原理是:
- 创建带有新结构的影子表。
- 利用触发器(TRIGGER)捕获原表的变更并同步到影子表。
- 数据同步完成后,原子性替换原表。
示例命令:
pt-online-schema-change D="dbname,tblname" --alter="ENGINE=InnoDB" --execute
InnoDB特定优化:OPTIMIZE TABLE
对于InnoDB表,OPTIMIZE TABLE
会重建表并整理碎片,但本质与ALTER TABLE ENGINE=InnoDB
类似:
OPTIMIZE TABLE table_name;
注意:在MySQL 5.6之前,此操作会锁表;5.6及之后版本,InnoDB支持在线DDL,但需确保innodb_online_alter_log_max_size
参数配置合理。

分区表重组
对于分区表,可单独重建某个分区:
ALTER TABLE table_name REBUILD PARTITION partition_name; ALTER TABLE table_name REORGANIZE PARTITION partition_name INTO (PARTITION partition_name VALUES LESS THAN (...));
重组操作的适用场景
- 表碎片率高:通过
information_schema.TABLES
表的DATA_FREE
字段判断碎片情况(DATA_FREE > 0
表示存在碎片)。 - 查询性能下降:全表扫描变慢,索引失效。
- 空间不足:回收未使用的空间以节省存储。
注意事项
- 锁表影响:
ALTER TABLE
和OPTIMIZE TABLE
在执行期间会锁定表,业务低峰期操作。 - 备份:重组前确保数据已备份,防止意外损坏。
- 主从复制:主库执行重组后,从库会同步操作,需监控复制延迟。
- 临时表空间:InnoDB重组时会产生临时表空间,需确保
innodb_temp_data_file_path
有足够空间。
重组前后对比示例
假设表t1
存在碎片,重组前后状态如下:
指标 | 重组前 | 重组后 |
---|---|---|
DATA_FREE | 100 MB | 0 MB |
索引深度 | 4 | 3 |
平均行长度 | 512 bytes | 500 bytes |
查询响应时间 | 50 ms | 20 ms |
相关问答FAQs
Q1: 如何判断MySQL表是否需要重组?
A1: 可以通过查询information_schema.TABLES
表检查DATA_FREE
列的值,若DATA_FREE
大于0,表示表存在碎片;若查询性能明显下降或SHOW TABLE STATUS
显示"Free bytes"较高,也可作为判断依据。
SELECT table_name, data_free FROM information_schema.TABLES WHERE table_schema = 'your_db' AND data_free > 0;
Q2: 重组大表时如何减少对业务的影响?
A2: 对于大表,建议采用以下方法降低影响:
- 使用
pt-online-schema-change
或gh-ost
等工具实现在线重组,避免锁表。 - 分批次重组:若支持分区,可逐个分区重组。
- 调整
innodb_online_alter_log_max_size
参数,增加在线DDL操作的日志容量,减少锁时间。 - 在业务低峰期执行重组操作,并监控数据库负载。