能,但仅限 like ‘abc%’ 这类前缀匹配;like ‘%abc’ 或 like ‘%abc%’ 默认无法使用 b+ 树索引,因 b+ 树只支持从左到右匹配,开头通配符导致无法定位起始位置而全表扫描。

LIKE 查询能走索引吗?取决于通配符位置
能,但仅限 LIKE 'abc%' 这类前缀匹配;LIKE '%abc' 或 LIKE '%abc%' 默认无法使用 B+ 树索引(除非用覆盖索引或倒排索引方案)。
mysql 的 B+ 树索引是按字典序存储的,只能高效支持「从左到右」的匹配。一旦开头是通配符,优化器就无法定位起始位置,只能全表扫描。
-
LIKE '张%'→ 可走name索引(前提是该列有索引) -
LIKE '%三'→ 不走索引,哪怕name有索引 -
LIKE '%王%'→ 同样不走索引,且无法利用前缀树特性
为什么加了索引还是没走?检查这几个点
即使写成 LIKE 'abc%',也可能因隐式类型转换、函数包裹或统计信息过期导致索引失效。
- 字段类型和参数类型不一致:比如
name VARCHAR(50)被和整数比较,触发隐式转换 →WHERE name LIKE 123会全表扫 - 在字段上用了函数:
WHERE UPPER(name) LIKE 'ABC%'→ 索引失效(可建函数索引:CREATE INDEX idx_name_upper ON t1 ((UPPER(name)))) - 查询条件中混用 OR 且部分分支无索引:
WHERE name LIKE 'a%' OR status = 1,可能让整个查询放弃索引 - 优化器认为全表扫描更快:比如表小、匹配行数多(> ~20% 总行数),可通过
EXPLAIN看type是否为range或ref
后缀/中缀模糊查怎么优化?绕不开的几个替代方案
真要查 '%关键词' 或 '%关键词%',原生 B+ 索引无解,得换思路:
- 全文索引(
FULLTEXT):适合中文需配合ngram插件(MySQL 5.7+),建索引:ALTER table t1 ADD FULLTEXT(name),查:select * FROM t1 WHERE MATCH(name) AGAINST('三' IN NATURAL LANGUAGE MODE) - 倒排表 / 冗余字段:把字符串拆成关键词存进关联表,或生成反向字符串字段(如
name_reverse),对后缀查转为前缀查:WHERE name_reverse LIKE REVERSE('三') + '%' - 前缀索引 + 应用层过滤:对长文本建前缀索引(
INDEX idx_name_10 (name(10))),先快速筛出可能项,再由应用做二次匹配 - ES 或 RedisSearch:超出 MySQL 能力边界时,应考虑专用搜索服务
LIKE 查询性能差的典型信号
别等用户投诉才查,这些现象说明模糊查询已成瓶颈:
-
EXPLAIN结果中rows值极大,且type是ALL -
SHOW PROFILE for QUERY N显示Copying to tmp table或Creating sort index耗时占比高 - 慢日志里反复出现
LIKE '%...'且Query_time> 1s - 并发稍高时 CPU 持续 90%+,
SHOW PROCESSLIST多个状态为Sending data
模糊查询的“模糊”本身就在牺牲确定性,越想查得全,越难快——真正需要的是明确业务场景下「够用」的精度和速度平衡,而不是强行让 LIKE '%xxx%' 走索引。