默认关闭innodb_stats_on_metadata即可避免元数据查询引发的统计抖动;当其为on且innodb_stats_persistent=off时,每次执行show table status等操作会遍历所有innodb表索引页更新统计,导致缓冲池污染、i/o飙升和执行计划不稳定。

默认关闭即可避免绝大多数元数据查询引发的统计抖动,无需额外操作;若已开启且遇到慢查询或I/O飙升,立刻设为OFF。
为什么SHOW TABLE STATUS会突然变慢甚至卡住
当innodb_stats_on_metadata=ON时,每次执行SHOW TABLE STATUS、SHOW INDEX,或查information_schema.TABLES等元数据表,InnoDB都会顺手触发一次索引统计更新(类似隐式执行ANALYZE TABLE)。这个过程不是只扫当前表,而是随机读取**实例中所有InnoDB表的索引页**——哪怕那些表你半年都没碰过。结果就是:
- 大量冷数据被读入
innodb_buffer_pool,挤掉热数据,造成“池污染” - 磁盘随机I/O暴增,尤其在表数量多(如>1000)、单表很大时,耗时可达分钟级
- 执行计划可能因统计信息临时漂移而劣化,表现为同一条SQL有时快有时慢
innodb_stats_on_metadata只在非持久化统计下生效
这个参数实际是否起作用,取决于innodb_stats_persistent的值:
- 如果
innodb_stats_persistent=ON(MySQL 5.7+ 默认),innodb_stats_on_metadata无论设成ON还是OFF都**不生效** - 只有当
innodb_stats_persistent=OFF时,innodb_stats_on_metadata才控制元数据访问是否触发统计更新 - 所以先确认你的统计模式:
SHOW VARIABLES LIKE 'innodb_stats_persistent';
多数生产环境应保持innodb_stats_persistent=ON,此时直接忽略innodb_stats_on_metadata更安全。
怎么关、什么时候关、关了有啥影响
执行以下命令即可关闭(需SUPER权限):
SET GLOBAL innodb_stats_on_metadata = OFF;
注意几点:
- 该设置是全局的,立即生效,无需重启
- 关闭后,
SHOW TABLE STATUS等操作不再触发统计更新,响应时间回归毫秒级 - 不影响
ANALYZE TABLE显式调用,也不影响innodb_stats_auto_recalc对数据变更的自动响应 - MySQL 5.6.6+ 默认就是
OFF,老版本(如5.5/5.6早期)才需手动关
真正容易被忽略的是:客户端启动时带--auto-rehash(mysql命令行默认行为)也会打开所有InnoDB表并触发统计更新——这时即使innodb_stats_on_metadata=OFF也挡不住。解决办法是加--disable-auto-rehash启动。











