首页/数据/SQL 速查/InnoDB 持久化统计信息
性能与执行计划72 条

InnoDB 持久化统计信息

统计信息落盘并可配置采样:8.0 默认持久化,重启后不丢;理解自动重算与采样页数有助于计划稳定。

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

持久化统计信息是什么

InnoDB 需要知道每个索引里大致有多少行、值的区分度如何,才能挑出执行计划,这类数据就是统计信息。MySQL 8.0 默认把它持久化到磁盘(innodb_stats_persistent 打开),实例重启后沿用而不再重新采样,计划因此更稳定。统计准不准,由「采样多少页」决定,采样页数就是拿准确度换代价的那个旋钮。

基本信息

innodb_stats_persistent默认 ON,统计信息落盘,重启后不重新估算
innodb_stats_auto_recalc默认 ON,表数据变动超过约一成时异步重算
innodb_stats_persistent_sample_pages默认 20,每个索引采样多少页
表级子句建表或改表时的 STATS_PERSISTENT、STATS_AUTO_RECALC、STATS_SAMPLE_PAGES
存放位置mysql.innodb_table_stats 与 mysql.innodb_index_stats

典型使用场景

  • 重启后保持计划稳定:避免每次重启都重新采样导致执行计划漂移
  • 关键表手动刷新:批量导入或大批删除后立刻重新统计
  • 大表采样调优:默认采样页对超大表偏少,估算偏差大时按需上调
  • 次要表降低成本:不重要的表调小采样页数,减少统计开销
  • 排查选错索引:先确认统计是否过期,再决定要不要写提示
  • 核对估算:查统计表里的数值与真实行数比对,定位失真环节

查看与调整

查看与调整
SHOW VARIABLES LIKE 'innodb_stats_persistent%';   # 查看持久化开关与采样页数
SHOW VARIABLES LIKE 'innodb_stats_auto_recalc';   # 确认自动重算是否开启
ALTER TABLE orders STATS_PERSISTENT=1, STATS_AUTO_RECALC=1,   # 表级声明优先于全局设置
  STATS_SAMPLE_PAGES=64;                                       # 这张表每次采样 64 页
ANALYZE TABLE orders;                             # 立即重新统计,不等后台重算
SELECT table_name, n_rows, clustered_index_size    # 查看落盘的表级统计
FROM mysql.innodb_table_stats WHERE database_name = 'app';
SELECT index_name, stat_name, stat_value           # 查看各索引的基数与页数估算
FROM mysql.innodb_index_stats
WHERE database_name = 'app' AND table_name = 'orders';

参数逐项读法

参数默认值影响
innodb_stats_persistentON关闭后统计只存内存,重启与部分元数据操作会触发重新采样
innodb_stats_auto_recalcON控制数据变动超阈值后是否自动重算
innodb_stats_persistent_sample_pages20调大更准但统计更慢,调小省事但估算会飘
innodb_stats_transient_sample_pages8只在使用非持久化统计时起作用
STATS_SAMPLE_PAGES(表级)跟随全局可按表的重要性分级,热点表给更大值
自动重算有阈值也有延迟:它按「变更行数占比超过约一成」触发,而且是异步在后台执行的。刚完成大批量变更的关键表,直接执行 ANALYZE TABLE 比等它自己重算更可控。
排查估算偏差时,先查 mysql.innodb_index_stats 里的统计值与真实行数对比,确认是采样式统计失真还是分布问题;列级直方图与索引基数各管一段,不要混为一谈。
采样页数调大会同时放大手动 ANALYZE 与后台重算的 IO 成本,写入频繁的大表上要按重要性分级设置,不要全局一刀切。

易错点

  • 改完数据干等自动重算:它有阈值与延迟,关键表批量变更后应手动重新统计
  • 采样页数设得过大:统计本身的 IO 成本上升,可能牵连在线业务
  • 以为统计只有一份:持久化关掉后统计存在内存里,重启即重新估算,计划会漂移
  • 只看估算行数就下结论:估算来自采样,大表上本就存在偏差,需与真实行数核对
  • 忽略表级声明:表上的 STATS_* 设置会覆盖全局参数,改动前先确认原配置

数据来源与参考

  • MySQL 8.0 Reference Manual · InnoDB Persistent Statistics
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌