MySQL升级后必须执行ANALYZE TABLE更新统计信息,统一显式声明collation避免索引失效,并检查函数索引兼容性、哈希连接与并行查询内存配置,否则易致查询变慢且无报错。

MySQL升级后索引统计信息可能过期,导致执行计划劣化
MySQL 5.7 升级到 8.0 或跨大版本迁移(如 5.6 → 8.0)时,INFORMATION_SCHEMA.STATISTICS 和 mysql.innodb_index_stats 中的统计信息不会自动重建。优化器依赖这些数据估算行数,一旦失真,可能选错索引甚至走全表扫描。
- 升级后立即执行
ANALYZE TABLE(对每个关键表),不是“建议”,是必须操作 - 8.0 默认启用
innodb_stats_auto_recalc=ON,但仅对数据变更超 10% 的表触发;冷迁移后无变更,不会自动更新 - 若使用
mysqldump导入,导入完成后再ANALYZE TABLE,不要在导入过程中穿插执行
8.0 的默认排序规则(collation)变更会隐式影响索引匹配
MySQL 8.0 将默认 collation 从 utf8mb4_general_ci 改为 utf8mb4_0900_as_cs(大小写敏感、重音敏感)。如果原库字段定义未显式指定 collation,升级后新建索引或 ALTER 表时可能用新规则,导致 WHERE name = 'ABC' 无法命中旧索引(因排序规则不一致,优化器判定无法使用)。
- 检查现有索引字段的 collation:执行
SHOW FULL COLUMNS FROM table_name LIKE 'col_name';,确认Collation列是否统一 - 迁移前统一显式声明 collation,例如建表时写
name VARCHAR(64) COLLATE utf8mb4_unicode_ci,避免依赖默认值 - 升级后用
EXPLAIN FORMAT=TREE查看实际是否用索引;若显示Using where; Using index消失,优先怀疑 collation 不匹配
函数索引(8.0.13+)在迁移中容易被忽略或误用
如果你在 8.0 环境中创建了函数索引(如 CREATE INDEX idx_email_domain ON users ((SUBSTRING_INDEX(email, '@', -1)));),而目标环境是 5.7 或早期 8.0 版本,mysqldump 会导出语法错误的建表语句,恢复失败。
- 检查是否用了函数索引:
SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = 'db' AND INDEX_NAME LIKE 'func%'; -
mysqldump --skip-log-bin --no-tablespaces仍会输出函数索引语法;需手动替换或用--skip-routines --skip-triggers --skip-events并额外处理索引 - 函数索引对表达式有严格限制(不能含用户变量、存储函数、非确定性函数),迁移后若查询变慢,先查
SHOW CREATE TABLE是否真建成功,再查EXPLAIN是否命中
并行查询(8.0.14+)和哈希连接开启后,内存配置不当反而拖慢简单查询
8.0 默认启用 hash_join=ON 和 parallel_query=ON(部分版本),对 JOIN 性能提升明显,但会显著增加 join_buffer_size 和 cte_max_recursion_depth 等内存消耗。小规格实例(如 2C4G)若未调低阈值,简单两表 JOIN 可能因等待并行资源或哈希构建失败而退化为更慢路径。
- 上线前验证:在测试环境关掉并行和哈希连接(
SET SESSION optimizer_switch='hash_join=off,parallel_query=off';),对比关键查询的EXPLAIN ANALYZE输出 - 生产环境若保留开启,务必设置
max_execution_time防止长哈希构建阻塞其他连接 - 注意
optimizer_switch是会话级变量,应用连接池需在初始化 SQL 中显式关闭,不能只靠全局配置
函数索引语法兼容性、collation 隐式继承、统计信息滞后——这三个点在升级或迁移后最常引发“没改代码,查询突然变慢”的问题,且日志里几乎不报错,只能靠 EXPLAIN 和 SHOW CREATE TABLE 对比定位。











