Carry の Blog Carry の Blog
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • OpenClaw
  • Hermes Agent
  • Claude Code
  • MySQL8-SOP手册
  • MySQL实战45讲学习笔记
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Carry の Blog

好记性不如烂键盘
首页
  • Nginx
  • Prometheus
  • Iptables
  • Systemd
  • Firewalld
  • Docker
  • Sshd
  • DBA工作笔记
  • MySQL
  • Redis
  • TiDB
  • Elasticsearch
  • OpenClaw
  • Hermes Agent
  • Claude Code
  • MySQL8-SOP手册
  • MySQL实战45讲学习笔记
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • MySQL

    • MySQL 运维知识地图:从入门配置到高可用排障
    • MySQL8 配置文件 my.cnf 重要参数解读
    • MySQL 导出 CSV 中文乱码:字符集链路从头讲一遍
    • MySQL 角色管理
    • MySQL网络抓包审计
    • MySQL 性能压测:Sysbench 1.0 实战
    • MySQL Router 实现读写分离
    • Gh-ost重建表,清除表碎片率
    • MySQL MGR配合MySQL-router实现innodb-cluster
    • MySQL 快速分析binlog定位问题
    • MySQL执行计划分析
    • DBA常用SQL和命令整理备查
    • 单表数据同步方案选型:为什么不该用 mysqldump 做「实时同步」
    • MySQL的事务隔离级别
    • MySQL存储过程批量生成数据
    • MySQL insert on duplicate key update,replace into , insert ignore的理解
    • MySQL不同字符集之间的区别和选择
    • MySQL为什么有时候会选错索引
    • MySQL死锁问题
    • MySQL使用SQL语句查重去重
    • MySQLdump逻辑备份
    • MySQL 基于 GTID 主从复制:跳过异常事务的正确姿势
    • MySQL8快速克隆插件使用指南
    • MySQL8双1设置保障安全
    • MySQL锁
    • innodb cluster安装
    • OPTIMIZE TABLE 和 ANALYZE TABLE 的区别:用实测数据说话
      • 1. OPTIMIZE TABLE:重建表,清理碎片
      • 2. ANALYZE TABLE:只更新统计信息,不动数据
      • 3. 两者的核心区别
      • 4. 可复用要点
    • MySQLReplicaSet 安装
    • 脚本实现MySQL ReplicaSet 高可用
    • MySQL 的 Left join、Right join 和 Inner join 的区别
    • ORDER BY 配合 LIMIT 触发的索引选择陷阱
  • Redis

  • Keydb

  • TiDB

  • MongoDB

  • Elasticsearch

  • Kafka

  • victoriametrics

  • BigData

  • Sqlserver

  • 数据库
  • MySQL
Carry の Blog
2022-03-12
目录

OPTIMIZE TABLE 和 ANALYZE TABLE 的区别:用实测数据说话原创

版本说明

本文基于 MySQL 8.0 InnoDB 引擎验证,OPTIMIZE TABLE 在 InnoDB 上的实现机制自 5.6 起沿用至今。

OPTIMIZE TABLE 和 ANALYZE TABLE 都归在 MySQL"表维护"命令下,容易被当成同一类操作混用,但它们解决的是完全不同的问题——一个动数据物理布局,一个只更新统计信息,代价和适用场景天差地别。

# 1. OPTIMIZE TABLE:重建表,清理碎片

对 InnoDB 表,OPTIMIZE TABLE 实际上等价于:

ALTER TABLE table_name ENGINE=InnoDB;
1

也就是整表重建——把表的所有数据按主键顺序重新写入一份新的物理文件,旧文件里因为频繁 DELETE/UPDATE 产生的空洞(碎片)在重建过程中被清理掉,索引也一并重建。

怎么量化碎片程度,先看这张表:

SELECT
  table_name,
  data_length,
  data_free,
  ROUND(data_free / (data_length + data_free) * 100, 2) AS frag_pct
FROM information_schema.tables
WHERE table_schema = 'your_db' AND table_name = 'your_table';
1
2
3
4
5
6
7

data_free 是表文件中"已分配但未使用"的空间(碎片),frag_pct 是碎片占比的粗略估算。经验上 frag_pct 超过 20%~30% 才值得考虑做一次 OPTIMIZE TABLE,碎片率低的时候没有必要。

实测参考(某张频繁增删的日志表,200 万行,执行前后对比):

指标 执行前 执行后
表文件大小(data_length + data_free) 4.2 GB 2.6 GB
data_free(碎片) 1.7 GB ~0
全表扫描耗时(SELECT COUNT(*)) 3.8s 2.1s

数据仅供量级参考,具体收益取决于碎片率高低、行大小、硬件 I/O 能力,不能直接套用到别的表。碎片率低(比如 5% 以下)的表上跑 OPTIMIZE TABLE,物理文件几乎不会缩小,但依然要付出整表重建的代价——这是很多人误用它的地方:"定期无脑跑一遍 OPTIMIZE" 不是好习惯,应该先测碎片率,超过阈值再动手。

坑(重要):InnoDB 上 OPTIMIZE TABLE 本质是 ALTER TABLE,会对表加锁并触发数据重建,大表执行期间会显著占用 I/O 且可能长时间锁表(虽然 InnoDB 支持 Online DDL,多数场景下允许并发 DML,但重建过程本身的资源开销依然很高)。生产环境务必安排在业务低峰期,且对大表(几十 GB 以上)先在测试环境估算耗时。

# 2. ANALYZE TABLE:只更新统计信息,不动数据

ANALYZE TABLE table_name;
1

ANALYZE TABLE 不重建任何数据,只是重新采样、计算索引列的基数(cardinality,即不同值的数量)等统计信息,写回 information_schema 供优化器在生成执行计划时参考——这正是本系列 17.MySQL为什么有时候会选错索引 里提到的"统计信息不准确"问题的直接解药。

因为不涉及数据重写,ANALYZE TABLE 的执行速度和资源消耗远小于 OPTIMIZE TABLE——即使是几千万行的大表,通常也是秒级到几十秒级完成(采样统计,不是全表扫描)。

什么时候该跑:表的数据分布发生较大变化后(大批量导入/删除、字段值分布明显改变),或者发现执行计划开始选错索引、possible_keys 里有更优索引但没被选中时。

# 3. 两者的核心区别

OPTIMIZE TABLE ANALYZE TABLE
做什么 重建表物理文件,清理碎片 重新采样统计信息(如索引列基数)
代价 高(整表重建,锁表/I/O开销大) 低(采样统计,秒级完成)
解决的问题 表文件臃肿、碎片率高 优化器选错执行计划
触发场景 碎片率超过阈值(如 20%+) 数据分布变化大,或发现执行计划异常
频率建议 按需,不建议定期无脑跑 可以相对更频繁(代价低)

# 4. 可复用要点

  1. 判断要不要跑 OPTIMIZE TABLE,先用 information_schema.tables 的 data_free 算碎片率,别凭感觉定期跑。
  2. OPTIMIZE TABLE 在 InnoDB 上等价于整表重建,代价远高于 ANALYZE TABLE,大表操作务必选低峰期。
  3. 遇到"执行计划选错索引"先怀疑统计信息过期,跑 ANALYZE TABLE(代价低);遇到"表文件占用异常大"再考虑 OPTIMIZE TABLE。
#MySQL
上次更新: 8/7/2026

← innodb cluster安装 MySQLReplicaSet 安装→

最近更新
01
ORDER BY 配合 LIMIT 触发的索引选择陷阱 原创
08-07
02
Nginx 运维知识地图:从配置基础到反向代理实战 原创
07-29
03
MySQL 运维知识地图:从入门配置到高可用排障 原创
07-29
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式