mysql 5.7升级8.0后索引“失效”主因是collation不一致引发隐式convert导致b+树索引无法使用,其次为order by方向/连续性校验变严及联合索引排序段断裂;需用explain与show full columns交叉验证并统一collation至utf8mb4_0900_ai_ci。

MySQL 5.7 升级到 8.0 后索引“失效”,绝大多数情况不是索引被删了或损坏了,而是查询执行计划跳过了它——核心原因集中在 COLLATION 不一致触发隐式 CONVERT、ORDER BY 方向严格校验、联合索引排序连续性要求变高 这三类问题上。修复前必须先确认是哪一类,否则改错方向只会白忙。
EXPLAIN 显示 key 有值但 Extra 出现 Using filesort
这说明索引被用于查找(WHERE 条件命中),但没被用于排序(ORDER BY 无法复用)。MySQL 8.0 对“索引能否同时服务 WHERE + ORDER BY”判断更严格。
- 检查索引定义和 ORDER BY 字段顺序是否完全对齐:比如索引是
INDEX(a, b DESC, c),那ORDER BY a ASC, b DESC, c ASC才可能免排序;写成ORDER BY a DESC, b DESC就会触发 filesort - 注意字段方向必须逐个匹配:MySQL 5.7 忽略 DESC/ASC,8.0 真正支持降序索引,也真正校验方向一致性
- 联合索引中,ORDER BY 字段必须是 WHERE 条件覆盖的最右连续段:索引
(status, category, updated_at),WHEREstatus = ? AND category = ?后只能接ORDER BY updated_at;若写ORDER BY status, updated_at,中间缺了category,8.0 直接弃用索引做排序
EXPLAIN 的 key 为 NULL 或 type 退化为 ALL
这是典型的隐式转换导致索引无法使用,90% 以上源于 COLLATION 不一致。MySQL 8.0 在比较前会自动加 CONVERT(col USING utf8mb4_0900_ai_ci),只要出现这个函数,B+ 树索引就必然失效。
- 用
SHOW FULL COLUMNS FROM t LIKE 'col'查列的Collation - 用
SELECT @@collation_connection查当前连接的排序规则 - 两者不一致(如列是
utf8mb4_general_ci,连接是utf8mb4_0900_ai_ci)就是根因 - JOIN 场景更危险:
ON t1.name = t2.name中只要任一字段 COLLATION 不同,就会在 join buffer 中全量转换,性能断崖
唯一索引插入报 Duplicate entry,但数据肉眼不同
比如 'testⅠ'(罗马数字 I)和 'testI'(英文字母 I)被判定重复,这是 utf8mb4_0900_ai_ci 的归一化行为所致——它把视觉相似字符(Ⅰ/I/I/í)视为逻辑等价。
- MySQL 5.7 默认用
utf8mb4_general_ci,按字节比,区分度低但“宽松” - MySQL 8.0 默认用
utf8mb4_0900_ai_ci,基于 Unicode 9.0,语言敏感、重音不敏感、大小写不敏感 - 升级后未显式修改表/列 COLLATION,旧数据仍按老规则存,但新查询按新规则比,冲突就暴露了
- 修复不能只改一边:ALTER TABLE … MODIFY col … COLLATE utf8mb4_0900_ai_ci 要配合应用层传参编码(JDBC 加
useUnicode=true&characterEncoding=utf8mb4)
真正容易被忽略的是:COLLATION 不一致的问题往往藏在 JOIN、子查询、函数参数里,单表 WHERE 看着正常,一关联就崩;而 ORDER BY 失效常被误判为“索引没建好”,其实只是方向或连续性差了一位。











