bigywater.tech
MySQL / InnoDB · 74

OPTIMIZE TABLE 到底做了什么

对一张经历过大量删除的表跑OPTIMIZE TABLE,看MySQL真实说了什么、又真实做了什么,验证它到底是不是真的整理了碎片。

Recreate + Analyze
MySQL真实给出的对InnoDB表OPTIMIZE的解释
约45%
真实的文件缩小比例

做的事:对一张删除过大量数据的表,真实跑一次OPTIMIZE

代码-- seq_pk此时已经经历过大量删除(延续前两篇的实验数据) OPTIMIZE TABLE seq_pk;

验证:MySQL真实自己说了它做了什么

实测 · 本机执行输出
Table   Op        Msg_type   Msg_text
seq_pk  optimize  note       Table does not support optimize, doing recreate + analyze instead
seq_pk  optimize  status     OK

这句提示信息真实是MySQL自己给出的解释:InnoDB(以及大多数现代存储引擎)并不真的支持"原地整理碎片"这种轻量操作,OPTIMIZE TABLE对它们来说真实被翻译成了ALTER TABLE ... FORCE——按主键顺序把全部数据重新读出来,构建一张全新的、紧凑排列的表,再替换掉旧表。这不是"碎片整理",是真实的"推倒重建"。

验证:真实的文件大小变化,缩了约45%

实测 · 本机磁盘真实文件大小
OPTIMIZE之前:  seq_pk.ibd = 360448 字节(只剩300行数据,但文件还是大表时期的大小)
OPTIMIZE之后:  seq_pk.ibd = 196608 字节

真实缩小了约45%
重建之后,数据按主键顺序紧凑地重新排列进最少数量的页面里,之前删除留下的、分散在各个页面里的空洞真实被彻底清除。这个操作的真实代价也很实在:ALTER TABLE ... FORCE本质是重建整张表,对InnoDB(自MySQL 5.6起)虽然真实支持在线DDL、不完全阻塞读写,但依然要读出全表数据重新写一遍,对一张几十GB的大表来说,这个操作真实会持续很长时间,还会真实消耗大量磁盘I/O和临时空间——不是一个可以随手在业务高峰期执行的轻量命令。

分步演示:OPTIMIZE TABLE前后的真实文件大小变化

每一步都是本文上面用真实磁盘文件跑出来的原始结果。

OPTIMIZE TABLE真实就是推倒重建
这一步新验证的状态

    本文用到的工具

    • 本机 MySQL 26.7.0(InnoDB),延续前两篇实验里已经删除过大量数据的表
    • OPTIMIZE TABLE真实的执行输出 + 真实磁盘文件大小对比
    京ICP备2026067502号-1京公网安备11010502063487号