MySQL升级后必须手动执行ANALYZE TABLE更新统计信息,否则EXPLAIN的rows值失真;需核验索引定义一致性、前缀长度、生成列索引有效性,并利用performance_schema识别僵尸索引,结合EXPLAIN FORMAT=TREE验证优化器行为变化。
升级后立刻检查 INFORMATION_SCHEMA.STATISTICS 是否同步更新
MySQL 升级(尤其是跨大版本,如 5.7 → 8.0)后,INFORMATION_SCHEMA.STATISTICS 中的索引统计信息可能未自动刷新,导致 EXPLAIN 显示的 rows 严重失真,误判索引有效性。
- 执行
ANALYZE TABLE table_name;强制更新统计信息,不是可选操作,是必须步骤 - 对所有高频查询表批量执行:
SELECT CONCAT('ANALYZE TABLE ', table_schema, '.', table_name, ';') FROM information_schema.tables WHERE table_schema NOT IN ('mysql','information_schema','performance_schema','sys');,再复制结果运行 - 注意:8.0+ 默认启用
innodb_stats_auto_recalc=ON,但首次升级后仍需手动触发一次,否则旧统计值可能残留
用 SHOW INDEX 和 INFORMATION_SCHEMA.KEY_COLUMN_USAGE 核验索引定义一致性
升级过程本身不删除索引,但某些场景下索引会“失效”——比如列字符集变更、前缀长度超限、或使用了被弃用的语法(如 FULLTEXT 在非 utf8mb4 下行为异常)。
-
SHOW INDEX FROM table_name;看Sub_part是否为NULL或数值异常(如 8.0 中VARCHAR(255)字段建了INDEX(col(1000))会静默截断,实际生效前缀可能是 767 或 3072,取决于innodb_large_prefix和行格式) - 对比升级前后
SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = 'db' AND TABLE_NAME = 't';的COLUMN_NAME和ORDINAL_POSITION,确认复合索引字段顺序没被意外重排 - 特别检查含生成列(generated column)的索引:8.0.23+ 对
STORED列索引支持更严格,若升级后查询变慢,先查该索引是否仍在SHOW CREATE TABLE输出中
通过 performance_schema.table_io_waits_summary_by_index_usage 找“僵尸索引”
升级后是清理低效索引的黄金窗口——新版本的 performance_schema 表提供了更精确的索引使用统计,比旧版 Handler_read_* 状态变量更可靠。