
LIKE 查询为什么慢?先看执行计划
MySQL 对 LIKE 的索引使用非常敏感,不是加了索引就生效。比如 WHERE name LIKE '%abc',哪怕 name 有 B+ 树索引,也基本走全表扫描——因为 B+ 树只支持最左前缀匹配,而前导通配符(% 开头)让优化器无法定位索引起点。
实操建议:
- 用
EXPLAIN SELECT ...看type是否为range或ref;如果是ALL,说明没走索引 - 注意
key字段是否显示实际使用的索引名;NULL表示完全未用索引 - 避免在
LIKE左侧对字段做函数或表达式,例如UPPER(name) LIKE 'ABC%',会直接失效索引
哪些 LIKE 模式能用上索引?
只有“右模糊”或“固定前缀 + 右模糊”才可能触发索引查找,本质是利用 B+ 树的有序性做范围扫描。
能走索引的典型写法:
-
WHERE name LIKE 'abc%'→ 匹配以 abc 开头的所有值,可用name上的普通索引 -
WHERE name LIKE 'abc_def%'→ 下划线不破坏前缀连续性,仍可索引定位 WHERE name >= 'abc' AND name → 手动等价改写,更明确、兼容性更好
不能走索引的写法:
-
WHERE name LIKE '%abc'→ 前导 %,必须全表扫 -
WHERE name LIKE '%abc%'→ 中间模糊,同样无法利用索引顺序 -
WHERE name LIKE 'ab%c'→ 中间带 %,B+ 树无法跳过中间段继续比对
想查中间或后缀?别硬扛 LIKE,换方案
当业务真需要 %abc% 或 %abc 这类查询时,强行加索引没用,得换技术路径。
实操建议:
- 全文索引(
FULLTEXT)适合长文本关键词搜索,但仅支持MyISAM和InnoDB(5.6+),且对单字、停用词、最小长度有限制 - 倒排索引类方案:把字段内容分词后存到专用搜索引擎(如 Elasticsearch、Meilisearch),MySQL 只存 ID 和原始数据
- 冗余字段法:如果只查固定后缀(如邮箱域名),可额外存
domain字段并建索引,WHERE domain = 'gmail.com' - 生成式前缀:对需后缀匹配的字段,反向存储(如把
user@example.com存成moc.elpmaxe.reusu),再用LIKE 'moc.elpmaxe%'
LIKE 性能还受哪些隐性因素影响?
即使写法正确,LIKE 查询也可能变慢,问题常藏在细节里。
容易被忽略的点:
- 字符集和排序规则不一致:比如列是
utf8mb4_unicode_ci,而参数传的是utf8mb4_general_ci,可能导致隐式转换,索引失效 - 索引长度不足:
VARCHAR(255)列只建了前 100 字符索引(INDEX(name(100))),而查询'abc...'超过 100 字节,照样无法精确定位 - 统计信息过期:
ANALYZE TABLE没跑过,优化器误判行数,可能放弃本可用的索引 - 参数化查询绑定类型错误:用 ORM 时把字符串参数绑成
INT类型,触发隐式类型转换,索引失效
复杂点在于:同一个 LIKE 语句,在不同数据分布、不同 MySQL 版本、不同配置下,执行计划可能完全不同。别只信“理论上能走索引”,上线前一定用真实数据量 + EXPLAIN FORMAT=JSON 验证。










