mysql升级或迁移是否会影响索引优化_mysql性能注意事项

来源:这里教程网 时间:2026-02-28 20:46:06 作者:

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
对比定位。

相关推荐