mysql如何优化带有like条件的查询_mysql索引失效分析

来源:这里教程网 时间:2026-02-28 20:51:54 作者:

LIKE 查询为什么慢?本质是索引无法跳过全表扫描

WHERE name LIKE '%abc'
WHERE name LIKE '%abc%'
出现时,MySQL 通常无法使用 B+ 树索引的有序性做快速定位,只能从索引最左前缀开始逐条比对,最终退化为索引扫描(index scan)甚至全表扫描(table scan)。只有
LIKE 'abc%'
这种左匹配才可能走索引范围查询。

哪些 LIKE 写法能用上索引?看前导通配符是否存在

能否命中索引,关键看通配符是否出现在模式最左侧:

WHERE col LIKE 'abc%'
→ 可用索引,B+ 树按字典序查找以
'abc'
开头的所有值
WHERE col LIKE 'ab_c'
→ 可用索引(下划线只占一位),仍属于左匹配前缀
WHERE col LIKE '%abc'
→ 索引失效,必须倒序扫描,MySQL 不支持反向索引遍历
WHERE col LIKE '%abc%'
→ 索引失效,无有效起始点
WHERE col LIKE 'ab%c'
→ 索引部分生效,只加速到
'ab'
前缀,后续仍需字符串匹配

除了改写 LIKE,还有哪些实际可行的优化手段?

不能改 SQL?那就绕开 LIKE。常见且有效的替代路径有:

用全文索引 +
MATCH ... AGAINST()
替代模糊匹配,尤其适合中文需配合
ngram
插件或
MeCab
对固定长度后缀查询(如查文件扩展名),可新增计算列:
ALTER TABLE t ADD COLUMN ext VARCHAR(10) STORED AS (SUBSTRING_INDEX(filename, '.', -1))
,再对
ext
建索引
将高频模糊搜索字段同步到 Elasticsearch 或 RedisSearch,由专用搜索引擎承担 如果业务允许,把
LIKE '%keyword%'
拆成“关键词前置”+“关键词后置”两个条件并集,再用覆盖索引减少回表

如何确认你的 LIKE 查询到底有没有走索引?

别猜,用

EXPLAIN
看执行计划,重点关注这几项:

type
字段:出现
ALL
表示全表扫描;
range
ref
才算走了索引
key
字段:显示实际使用的索引名,为空即未命中
rows
字段:预估扫描行数,远大于结果集数量就是低效信号
注意隐式转换:比如
col VARCHAR(50)
被与整数比较(
WHERE col = 123
),会导致索引失效,LIKE 同理 —— 若字段是 utf8mb4_bin 排序,但查询用的是非二进制 collation,也可能触发隐式转换

真正容易被忽略的是字符集和排序规则不一致引发的隐式转换,它不会报错,但会让

EXPLAIN
显示用了索引,实际性能却接近全表扫描。

相关推荐