首页/数据/SQL 速查/表空间回收与重建:OPTIMIZE / VACUUM FULL
性能与执行计划72 条

表空间回收与重建:OPTIMIZE / VACUUM FULL

大量删除后空间不一定归还:MySQL 的 OPTIMIZE TABLE 对 InnoDB 近似重建表;PostgreSQL 用 VACUUM FULL 或 pg_repack。

SQL 速查数据更新于 2026-10-13

空间不一定自动归还

大量删除后磁盘空间不一定还回来:MySQL 的 OPTIMIZE TABLE 对 InnoDB 近似等于重建表并更新统计信息;PostgreSQL 的常规清理只把空间标记为可复用、通常不缩小文件,要真正归还空间得用 VACUUM FULL 或 pg_repack 这类工具。

基本信息

MySQL OPTIMIZE TABLE对 InnoDB 近似重建表并更新统计,释放未使用空间
MySQL 等价写法ALTER TABLE … FORCE 也是重建手段之一
PG 常规清理autovacuum 处理死元组,但通常不缩小文件
PG 归还空间VACUUM FULL 重写表并加排他锁
在线替代pg_repack 扩展,锁影响更小

典型使用场景

  • 大批量删除后磁盘告急
  • 表文件碎片多、顺序扫描明显变慢
  • 统计信息陈旧导致计划不准
  • 归档清理后想真正释放空间
  • 迁移或升级前重建目标表

MySQL 写法

MySQL 写法
OPTIMIZE TABLE orders;
-- 对 InnoDB 近似等价于重建表并更新统计,释放未使用空间

ALTER TABLE orders FORCE;   -- 重建的等价写法之一

-- 重建期间需要与原表相当的额外磁盘空间,先确认余量

PostgreSQL 写法

PostgreSQL 写法
VACUUM (VERBOSE) orders;    -- 常规清理,通常不缩小文件
VACUUM FULL orders;         -- 重写表并归还空间(持有排他锁)

-- 在线替代方案:pg_repack 扩展,减少长时间锁表

各动作对照

动作会缩小文件吗锁与代价
MySQL OPTIMIZE TABLE会(重建)需要额外空间,期间写入受影响
MySQL ALTER TABLE FORCE会(重建)同上
PG VACUUM通常不会只标记空间可复用,代价低
PG VACUUM FULL会排他锁,期间表不可用
pg_repack会锁影响小,需额外空间
重建类操作都应与业务低峰配合:VACUUM FULL 持有排他锁,期间查询与写入都会阻塞;OPTIMIZE TABLE 需要额外磁盘余量,空间不足会中途失败。
日常清理交给自动清理即可:频繁手工重建既消耗 IO 也拿不到等比例收益,只有确认空间确实需要归还、或统计信息陈旧时才做。
重建前先量化收益:对比重建前后的表文件大小与顺序扫描耗时,确认收益明显再安排窗口期,否则只是白花一波 IO。
归档策略比反复重建更重要:把历史数据定期迁出,表本身就不会膨胀到需要频繁重建,长期看这才是省事的做法。

易错点

  • 频繁执行 OPTIMIZE 或 VACUUM FULL:重建的 IO 与锁代价高,常规清理交给 VACUUM 与自动清理
  • 磁盘余量不足时重建:需要与原表相当的额外空间,空间不够会中途失败
  • 在业务高峰期做 VACUUM FULL:持有排他锁,期间表不可用
  • 以为 VACUUM 就能缩小文件:常规清理只是标记空间可复用,文件大小通常不变
  • 忽略重建后的统计信息变化:重建往往伴随统计更新,重要查询上线前要复核计划

数据来源与参考

  • MySQL 8.0 Reference Manual · OPTIMIZE TABLE Statement
  • PostgreSQL Documentation · Routine Vacuuming
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌