最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
MySQL 5.7升级后索引失效为什么会发生?
时间:2026-08-14 10:42:49 编辑:袖梨 来源:一聚教程网
MySQL 8.0索引未丢失但被优化器拒绝使用,根本原因是校验变严:SPATIAL字段缺失NOT NULL或SRID、JSON字段直接函数查询、字符串列排序规则不匹配等导致类型不安全,触发隐式转换或索引降级;需先修正字段定义、更新统计信息、统一SRID与COLLATE,再重建索引。
不是索引“丢了”,而是优化器拒绝使用——升级后执行计划变了,EXPLAIN 显示 type=ALL、key=NULL,但 SHOW INDEX 仍能看到索引名,说明索引元数据还在,只是被跳过了。
为什么 MySQL 8.0 会突然不认老索引?
核心原因是校验变严了:5.7 允许隐式行为(比如字段允许 NULL、默认 SRID 为 0、字符集排序规则宽松),而 8.0 要求显式声明、类型安全、规则对齐。一旦字段定义或查询写法和新规则冲突,优化器就直接放弃索引。
-
SPATIAL字段没设NOT NULL或缺失SRID→ 索引降级为BTREE -
JSON字段上直接用JSON_EXTRACT()查询 → 函数调用无法走 B+ 树索引 - 字符串列是
utf8mb4_bin,但查询条件没指定COLLATE→ 触发隐式转换,索引失效 - 联合索引
(a,b,c),查询只写WHERE b = 1→ 最左前缀断裂,5.7 和 8.0 都不走
怎么快速确认是不是真失效?
别猜,直接看 EXPLAIN 输出三项:
-
type是ALL(不是range/ref) -
key是NULL(没选任何索引) -
rows接近表总行数(比如 10 万行的表,rows=98234)
三者同时出现,基本就是索引被绕过了。注意:Extra 里出现 Using filesort 不代表索引失效,可能是排序没覆盖。
哪些修复动作最容易被跳过?
很多人重建索引或加函数索引,却漏掉前置约束变更,导致静默失败:
-
SPATIAL索引重建前,必须先ALTER TABLE t MODIFY geom POINT NOT NULL SRID 4326—— 少一个NOT NULL,CREATE SPATIAL INDEX就会报错,但SHOW INDEX还显示旧索引残留 -
JSON生成列没显式指定COLLATE,和源字段排序规则不一致 → 索引建了也白建,查询时隐式转换直接跳过 - 升级后没跑
ANALYZE TABLE t,统计信息还是 5.7 的旧值 → 优化器误判成本,宁可全表扫也不走索引
最隐蔽的坑不在“建不建索引”,而在字段定义、排序规则、统计信息这三处是否同步更新——它们不动,光改查询或加索引,大概率白忙。