like '%关键词' 不走索引,因b+树仅支持从左到右匹配,后缀或中缀通配无法定位起始位置,导致全表扫描;而 '关键词%' 可定位前缀并范围遍历,故能用索引。

LIKE '%关键词' 为什么完全不走索引
因为B+树索引的物理结构决定了它只能从左到右逐字符匹配。索引页中键值是按字典序严格排序的,比如 apple、banana、application,它们在叶子节点里是连续存储的。当查询条件是 name LIKE '%pple' 时,数据库无法定位起始位置——“以 pple 结尾”的值可能散落在任意分支上,必须扫描全部叶子节点才能确认,等价于全表扫描。
为什么 '关键词%' 能用索引而 '%关键词%' 不能
前缀匹配 name LIKE 'app%' 可以直接定位到第一个 app 开头的键值(比如 apple),然后向右顺序遍历所有满足前缀的记录,B+树天然支持这种范围扫描。但中间或结尾通配(如 '%pp%' 或 '%ple')破坏了有序性约束,优化器判断走索引反而比全表扫描更慢,于是直接放弃索引。
EXPLAIN 看得见的证据:key 列为 NULL
执行 EXPLAIN SELECT * FROM user WHERE name LIKE '%li%'; 后,观察输出中的 key 字段:如果显示 NULL,说明索引未被使用;同时 type 很可能为 ALL。这和 WHERE name LIKE 'li%' 的结果形成鲜明对比——后者 key 会显示对应索引名,type 通常是 range。
不是加了索引就万事大吉,关键看查询写法
即使你在 name 上建了单列索引,甚至联合索引 idx_name_age,只要 WHERE 条件里出现 LIKE '%...',整个索引对这一查询就形同虚设。真正起作用的从来不是“有没有索引”,而是“查询能否被转换成 B+ 树可加速的区间查找”。业务上真要支持后缀或模糊中缀搜索,得换技术栈——比如用 fulltext 索引(仅 MyISAM/InnoDB 部分版本)、倒排索引(ES)、或者预计算后缀数组。











