LIKE 查询为什么慢?本质是索引失效
MySQL 的
LIKE查询在模糊匹配时极易跳过索引,尤其是以通配符开头(如
LIKE '%abc')——这时优化器无法使用 B+ 树索引的有序性,只能全表扫描。即使字段上有索引,
EXPLAIN也会显示
type: ALL或
key: NULL。
哪些 LIKE 形式能走索引?必须满足左前缀匹配
只有
LIKE 'abc%'这类「固定前缀 + 后缀通配」才能利用索引的最左前缀原则。注意以下细节:
LIKE 'abc%'✅ 可用索引(B+ 树从 'abc' 开始向右遍历)
LIKE 'ab%c'❌ 不可用(中间有通配符,无法确定范围边界)
LIKE '%abc'❌ 不可用(无确定起始点)
LIKE 'abc\_def'✅ 可用(
_是单字符通配,不破坏前缀连续性) 如果字段是
VARCHAR(255)但实际值平均长度仅 10,建索引时可考虑前缀索引:
INDEX (col_name(10)),避免索引过大拖慢写入
无法改写为前缀匹配时,替代方案有哪些?
当业务必须支持任意位置匹配(如搜索标题含关键词),硬扛
LIKE '%keyword%'性能极差,应换思路: 用全文索引:
ALTER TABLE t ADD FULLTEXT(col_name),再用
MATCH(col_name) AGAINST('keyword' IN NATURAL LANGUAGE MODE) —— 支持分词、停用词、相关性排序,但只适用于 MyISAM或
InnoDB(5.6+) 引入外部搜索引擎:Elasticsearch 或 Meilisearch,适合高并发、复杂检索场景;MySQL 仅存原始数据 冗余字段预处理:如提取关键词生成
tags字段,用
FIND_IN_SET()或 JSON 匹配,配合普通索引 慎用
REGEXP:它比
LIKE更慢,且完全无法用索引
字符集和排序规则对 LIKE 性能有隐性影响
同一查询在不同 collation 下可能走/不走索引。例如:
utf8mb4_unicode_ci:大小写不敏感,但比较开销大,且某些组合会让优化器放弃索引(尤其涉及函数隐式转换时)
utf8mb4_bin或
utf8mb4_0900_as_cs:二进制或大小写敏感排序,匹配更直接,索引利用率更高 检查字段 collation 是否与查询字面量一致:
SELECT COLLATION(col_name), COLLATION('abc');若不一致,MySQL 会隐式转换,导致索引失效
避免在 WHERE中对字段用函数:
WHERE UPPER(col) LIKE '%ABC%'→ 索引必然失效 真正卡住性能的往往不是 LIKE 本身,而是没意识到「索引只帮得上左前缀」这个硬约束。一旦需求突破这个边界,就得跳出 SQL 做架构级取舍——要么换存储引擎,要么加搜索中间件,而不是在
LIKE上反复调参。
