导读:本期聚焦于孙悟空创作的《mysql为什么Like模糊查询不走索引?解析器如何判定通配符位置》,敬请观看详情。把%写在Like模式开头时,MySQL优化器为何直接放弃索引?这要从SQL解析器对通配符位置的判定逻辑说起。解析阶段,语法树会记录模式串中首个通配符出现的位置,若前缀为可变部分,B+树的有序性便无法被用来缩小扫描范围。对比前缀固定写法,后者能转化为范围查找并命中索引。许多慢查询源于误用前后模糊匹配,了解解析器的判定规则有助于重写语句、建立更合理的索引,从而把全表扫描降为索引范围扫描。

在MySQL的使用过程中,Like模糊查询是非常常见的需求,但很多同学会发现,同样的字段加了索引,有时查询飞快,有时却变成全表扫描。核心原因并不在索引本身,而在于MySQL解析器对Like模式中通配符位置的判定。当优化器在生成执行计划时,会依据解析器产出的语法树信息,判断这个Like条件能否利用B+树索引的有序特性。

mysql为什么Like模糊查询不走索引?解析器如何判定通配符位置

解析器如何识别Like模式中的通配符位置

MySQL接收到一条带有Like的SQL后,首先由词法分析和语法分析器将其转化为抽象语法树。对于形如 column LIKE 'abc%'column LIKE '%abc' 的表达式,解析器会把模式字符串作为一个常量字面量处理,并扫描其中 %_ 的位置。特别关键的是,解析器会标记“第一个通配符之前是否存在固定前缀”。如果模式以固定字符开头,例如 'abc%',解析器记录前缀为 abc,后续为可变部分;如果以 % 开头,则前缀长度为0。

这一判定结果会写入语法树节点,并传递给优化器。优化器在考虑是否使用二级索引时,本质上是看能否把Like条件转换成索引上的范围边界。B+树索引的叶子节点按键值有序排列,只有当我们知道“最小值起点”时,才能从某个位置开始顺序向后读。前缀固定的模式正好提供了这个起点,而前缀不固定则意味着任何索引项都可能是匹配项,优化器只能选择放弃索引。

可以通过 EXPLAIN 验证这一行为。在下面的示例中,我们创建一张用户表并对 name 字段建立索引,然后分别用前缀固定和前缀模糊的写法观察 type 列的变化。这能直观说明解析器给出的通配符位置信息如何决定执行路径。

CREATE TABLE user (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(50),
  KEY idx_name (name)
);

-- 前缀固定,解析器判定有固定前缀,可能使用范围扫描
EXPLAIN SELECT * FROM user WHERE name LIKE '张%';

-- 前缀模糊,解析器判定前缀长度为0,通常全表扫描
EXPLAIN SELECT * FROM user WHERE name LIKE '%伟';

为什么通配符在前的模式无法利用B+树索引

要理解为何 '%abc' 不走索引,需要回到B+树的结构特性。假设 name 索引中依次存在 李四王伟张伟赵刚。当我们查询 LIKE '张%' 时,优化器知道所有以“张”开头的字符串在索引里是连续的一段,可以定位到 的起始并向右扫描直到不以 开头为止,这就是典型的范围查找。

但如果是 LIKE '%伟',意味着只要结尾是“伟”就满足条件。在有序的B+树中,王伟张伟 之间可能夹杂着大量不以 结尾的记录,没有任何连续的物理或逻辑区间能覆盖所有候选值。优化器即便强行从索引读取,也得遍历每一个叶子节点去判断后缀,代价与全表扫描无异,因此它会直接选择扫描聚簇索引(全表)。

有些同学会问,MySQL不是有“索引下推”或“覆盖索引”吗?确实,如果查询只涉及索引列且使用了 INDEX 提示,某些版本可能在索引上做过滤,但依旧要遍历全部索引项,本质还是全索引扫描,并非通过通配符位置做的范围裁剪。解析器给出的“无固定前缀”结论,从根本上关闭了范围边界推导的可能。

-- 即使只查索引列,前缀模糊仍要扫全部索引项
EXPLAIN SELECT name FROM user WHERE name LIKE '%伟';
-- type 通常为 index(全索引扫描)而非 range

如何通过改写查询与调整结构规避索引失效

面对必须按后缀或中间内容匹配的诉求,一味依赖 LIKE '%xx' 并不可取。第一种思路是业务层拆分:如果后缀集合有限,可以冗余一个反转字段,例如 name_reverse 存储 name 的反转串,并把查询改写为 LIKE '魏%'(反转后的前缀)。这样解析器又能识别出固定前缀,正常走索引。

第二种思路是使用全文索引。MySQL从5.6起对InnoDB提供 FULLTEXT 索引,它基于倒排结构,不依赖B+树的前缀有序性,能够支持任意位置的关键字匹配。虽然全文索引的语法是 MATCH...AGAINST 而非Like,但在搜索场景中可以替代前后模糊查询,性能远优于全表扫描。

第三种是在设计阶段避免模糊后缀查询。如果系统是日志检索类,可以考虑把需要后缀检索的维度移到Elasticsearch等搜索引擎;若必须在MySQL内解决,结合生成列与索引也是可行方案。下面的例子展示用生成列存储反转串并建立索引,让解析器在改写后的查询中识别到固定前缀。

ALTER TABLE user ADD COLUMN name_reverse VARCHAR(50)
  GENERATED ALWAYS AS (REVERSE(name)) STORED;
ALTER TABLE user ADD INDEX idx_name_reverse (name_reverse);

-- 原需求:找以'伟'结尾的名字
-- 改写为反转后的前缀匹配
SELECT * FROM user WHERE name_reverse LIKE '伟%';

综上,MySQL的Like是否走索引,完全取决于解析器对通配符位置的判定结果。把通配符放在开头会抹去固定前缀,使B+树失去范围边界;通过结构冗余、全文索引或外部搜索引擎,我们能够在保留查询语义的同时,重新获得高效的检索路径。

mysqlLike模糊查询索引失效修改时间:2026-08-23 23:42:38

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。