B+树索引仅支持左前缀匹配,LIKE '%abc' 因前导%无法利用索引有序性,必须全表扫描;而'john%'、'jo%hn'等开头固定模式仍可走索引。

因为索引(尤其是 B+ 树)依赖字段值的**前缀有序性**来快速定位数据,而 LIKE '%abc' 这类左模糊查询无法利用这个特性,数据库只能全表扫描。
索引结构决定了它只能“从左匹配”
B+ 树索引把字符串按字典序排列,比如 alice、bob、carol、charlie。查找 'ca%' 时,数据库知道所有匹配项一定集中在 ca 开头的连续区间,可以快速跳转;但查 '%lia' 时,alia、blia、clia……可能散落在树的任意分支,没法跳转,只能逐行检查。
不是“不支持 LIKE”,而是“不支持前导 %”
以下写法仍可走索引:
-
WHERE name LIKE 'john%'—— 右模糊,符合最左前缀原则 -
WHERE name LIKE 'jo%hn'—— 中间有通配符但开头固定,仍能定位起始范围 -
SELECT id, name FROM user WHERE name LIKE '%abc'—— 若(name, id)是联合索引且查询只涉及这两列,可能触发覆盖索引,避免回表(但依然不加速匹配本身)
真要查后缀或含中间匹配,有更合适的方案
单纯靠普通 B+ 树索引解决不了这类问题:
- 后缀查询(如
name LIKE '%ing'):可考虑倒序存储 + 右模糊,例如存gninom再查gni% - 任意位置匹配(如
LIKE '%abc%'):建议用全文索引(FULLTEXT)或专门的搜索引擎(Elasticsearch、Meilisearch) - 高频模糊需求:提前构建关键词映射表,或使用 n-gram 分词索引
小提醒:别被执行计划误导
有时 EXPLAIN 显示 key 非空,不代表模糊条件用了索引——可能是覆盖索引生效,或优化器选了其他可用索引(比如主键)。关键看 type 是否为 range 或 ref,而不是 ALL;再结合 key_len 和实际查询逻辑判断真正生效的部分。










