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%'走索引。
