MySQL索引失效的五大场景:①WHERE中对索引列使用函数/表达式;②LIKE以通配符开头;③隐式类型转换;④联合索引未遵循最左前缀原则;⑤索引过多或结构不匹配查询模式,需结合EXPLAIN验证。
WHERE 条件中对索引列使用函数或表达式
MySQL 无法使用索引进行快速查找,只要在 WHERE 子句里对索引列做了计算、函数调用或类型转换,优化器就会放弃走索引。比如 WHERE YEAR(create_time) = 2023 或 WHERE price + 10 > 100,哪怕 create_time 和 price 都建了索引,也会全表扫描。
- 改写为范围查询:
WHERE create_time >= '2023-01-01' AND create_time - 避免在索引列上做运算,把计算移到等号右边(如
WHERE price > 90而非WHERE price + 10 > 100) - 如果必须用函数,可考虑生成列(generated column)+ 索引:
ALTER TABLE orders ADD COLUMN year_create INT AS (YEAR(create_time)) STORED;
CREATE INDEX idx_year_create ON orders(year_create);
LIKE 查询以通配符开头
LIKE '%abc' 或 LIKE '%abc%' 会导致索引失效,因为 B+ 树索引是按字典序排序的,前缀不固定就无法定位起始位置。
- 能用
LIKE 'abc%'就绝不用LIKE '%abc' - 全文检索场景改用
FULLTEXT索引 +MATCH ... AGAINST - 模糊匹配需求强且数据量大时,考虑外部方案(Elasticsearch、Redisearch)
隐式类型转换导致索引失效
当索引列是字符串类型(如 VARCHAR),而 WHERE 中传入的是数字(WHERE mobile = 13812345678),MySQL 会自动把字段转成数字比较,触发全表扫描。同理,字符集不一致(如 utf8mb4 vs utf8)也可能触发隐式转换。