贝利信息

mysql索引什么时候会失效_mysql常见失效场景

日期:2026-01-22 00:00 / 作者:P粉602998670
MySQL索引可能因函数/表达式、隐式类型转换、LIKE前缀通配、NOT/!=/OR等操作而失效,需通过EXPLAIN验证并遵循裸列查询、统一类型、避免前导%等原则。

MySQL 索引不是建了就一定生效的——优化器会根据成本(cost)决定是否走索引,而很多看似合理的写法,实际会让索引完全失效。下面这几种情况,在日常 SQL 编写和线上慢查排查中高频出现,务必警惕。

WHERE 中对索引列用了函数或表达式

比如 DATE(create_time) = '2025-12-31'SUBSTR(phone, 1, 3) = '138'price * 1.1 > 100,这些都会让索引失效。

联合索引没按最左前缀使用

联合索引 KEY idx_name_age_city (name, age, city),以下查询会失效:

✅ 能走索引的写法必须从左开始连续使用:

WHERE name = '张三' ✔️ WHERE name = '张三' AND age > 20 ✔️ WHERE name = '张三' AND age = 25 AND city LIKE '上%' ✔️(注意:LIKE 后缀带 % 仍可用索引)

隐式类型转换导致索引“悄悄失效”

字段定义为 VARCHAR,但查询时传了数字:WHERE user_id = 12345 —— 看似没问题,实则触发隐式转换,等价于 WHERE CAST(user_id AS SIGNED) = 12345,索引失效。

LIKE 以通配符 % 开头 or 用了 NOT/!=/OR 等操作符

WHERE name LIKE '%三'WHERE status != 1WHERE name = '张三' OR age = 25,这些都极大概率触发全表扫描。

真正容易被忽略的一点:索引是否生效,不只看语法,更要看数据分布和优化器估算。比如一张只有 100 行的表,哪怕写了 WHERE id = ?,MySQL 也可能直接全表扫描——因为比走索引还快。所以别只信“我加了索引”,要信 EXPLAIN 的输出和真实执行时间。