MySQL升级后索引失效主因是执行计划变更,需用EXPLAIN确认key是否为NULL;更新统计信息(ANALYZE TABLE)、检查字符集/排序规则兼容性、创建函数索引可解决。
MySQL升级后索引失效,通常不是索引“真的没了”,而是查询执行计划发生了变化,导致优化器不再选择原有索引。这背后多与统计信息过期、隐式类型转换、字符集/排序规则变更、索引列函数化或新版本优化器行为调整有关。
先用 EXPLAIN 确认当前查询是否真的跳过了索引:
EXPLAIN SELECT ...,重点看 key 列是否为 NULL,type 是否退化为 ALL 或 index
Using filesort 或 Using temporary 不代表索引失效,但可能说明索引覆盖不全MySQL 8.0+ 默认启用 innodb_stats_auto_recalc,但升级后旧表统计信息可能未及时刷新,导致优化器误判成本:
ANALYZE TABLE table_name;
ALTER TABLE table_name ENGINE=InnoDB;(会重建聚簇索引和二级索引)ANALYZE TABLE table_name UPDATE HISTOGRAM ON col1, col2;
MySQL 5.7 升级到 8.0 时,默认字符集从 变为
latin1utf8mb4,且默认排序规则变为 utf8mb4_0900_ai_ci。若字段定义未同步更新,易引发隐式转换:
COLLATION:SHOW FULL COLUMNS FROM table_name LIKE 'col_name';
utf8mb4_general_ci 的值去查 utf8mb4_0900_ai_ci 字段,可能触发转换,使索引失效)WHERE col_name = 'xxx' COLLATE utf8mb4_0900_ai_ci,或统一修改列定义:ALTER TABLE t MODIFY col VARCHAR(100) COLLATE utf8mb4_0900_ai_ci;
MySQL 5.7 不支持函数索引,8.0+ 支持。若升级后在 WHERE 中用了表达式(如 WHERE UPPER(name) = 'ABC'),而未创建对应函数索引,则无法走索引:
CREATE INDEX idx_upper_name ON t ((UPPER(name)));