导读:本期聚焦于小伙伴创作的《mysql如何优化带有like条件的查询?mysql索引失效场景有哪些?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《mysql如何优化带有like条件的查询?mysql索引失效场景有哪些?》有用,将其分享出去将是对创作者最好的鼓励。

在mysql的查询场景中,使用like进行模糊匹配是非常常见的需求,但这类查询如果写法不当很容易导致索引失效,进而让查询变成全表扫描,大幅降低性能。了解like查询的索引使用规则,掌握对应的优化方法,是数据库性能优化的重要部分。

mysql如何优化带有like条件的查询?mysql索引失效场景有哪些?

like查询的索引失效规则

mysql中B+树索引是按照索引列的值有序存储的,like查询的索引使用情况主要和通配符的位置有关:

  • 当通配符%放在匹配字符串的开头时,比如like '%abc',索引会失效,因为无法确定匹配范围的起始点,只能全表扫描。
  • 当通配符%放在匹配字符串的结尾时,比如like 'abc%',索引可以正常使用,因为可以从abc开头的位置向后匹配。
  • 当通配符%同时出现在开头和结尾时,比如like '%abc%',索引同样会失效。

我们可以通过执行计划验证这个规则,假设有一张用户表user,在username字段上建立了普通索引:

-- 创建测试表
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 插入测试数据
INSERT INTO `user`(`username`, `age`) VALUES ('zhangsan', 20), ('lisi', 22), ('wangwu', 25), ('zhaoliu', 28);

-- 查看like查询的执行计划
EXPLAIN SELECT * FROM `user` WHERE `username` LIKE 'zhang%';
EXPLAIN SELECT * FROM `user` WHERE `username` LIKE '%san';

执行上述语句后可以看到,第一个查询的typerange,表示使用了索引范围扫描;第二个查询的typeALL,表示进行了全表扫描,索引没有生效。

like查询的优化方案

1. 尽量使用前缀匹配

如果业务允许,优先将%放在匹配字符串的末尾,使用like '前缀%'的形式,这样可以正常触发索引。比如要匹配所有姓张的用户,就可以写成like '张%',而不是like '%张%'

2. 使用覆盖索引

如果查询的字段都包含在索引中,即使like查询本身无法使用索引进行匹配,也可能会因为覆盖索引减少回表操作提升性能。比如上面的用户表,如果只需要查询usernameid字段,这两个字段都在idx_username索引中(主键id会默认加入二级索引的叶子节点),可以改写查询:

-- 使用覆盖索引的查询
EXPLAIN SELECT `id`, `username` FROM `user` WHERE `username` LIKE '%san%';

执行计划中的Extra字段会出现Using index,表示使用了覆盖索引,虽然还是需要扫描整个索引树,但不需要回表查询聚簇索引,性能比全表扫描要好。

3. 使用全文索引

如果需要进行全文模糊匹配,比如搜索内容中包含某个关键词,可以使用mysql的全文索引。首先给字段创建全文索引:

-- 创建全文索引
ALTER TABLE `user` ADD FULLTEXT INDEX `ft_idx_username` (`username`);

-- 使用全文索引查询
SELECT * FROM `user` WHERE MATCH(`username`) AGAINST('san');

全文索引适合长文本的模糊匹配场景,比like查询的效率高很多,但需要注意全文索引的分词规则,以及最小搜索长度等参数的配置。

4. 反向索引法

如果必须做后缀匹配(比如like '%abc'),可以把字段的内容反转后存储到一个新字段,给新字段建立索引,查询时把匹配条件也反转,变成前缀匹配。比如要匹配usernamesan结尾的记录:

-- 添加反转字段并建立索引
ALTER TABLE `user` ADD `username_reverse` varchar(50) DEFAULT NULL;
UPDATE `user` SET `username_reverse` = REVERSE(`username`);
CREATE INDEX `idx_username_reverse` ON `user`(`username_reverse`);

-- 查询时反转匹配条件
SELECT * FROM `user` WHERE `username_reverse` LIKE REVERSE('san') || '%';

这种方法需要额外维护反转字段,适合固定后缀匹配的场景。

其他常见的mysql索引失效场景

除了like查询的不当使用,还有很多其他情况会导致mysql索引失效:

  • 对索引字段进行函数操作或者表达式计算,比如WHERE YEAR(create_time) = 2023,索引会失效。
  • 查询条件中使用or连接,且or两侧的字段不是都有索引,索引会失效。
  • 查询条件中索引字段发生隐式类型转换,比如字符串字段用数字匹配,WHERE username = 123,索引会失效。
  • 查询优化器认为全表扫描比使用索引更高效,比如查询的数据量占表总数据量的比例很高时,会自动放弃使用索引。
  • 使用!=<>is nullis not null等条件时,部分情况下索引会失效。

总结

优化mysql中带有like条件的查询,核心是尽量避免通配符放在匹配字符串的开头,优先使用前缀匹配。如果无法满足前缀匹配的需求,可以根据场景选择覆盖索引、全文索引或者反向索引的方法。同时要熟悉其他索引失效的场景,在编写查询语句时避开这些坑,才能最大程度发挥索引的作用,提升数据库查询性能。

mysqllike查询优化索引失效覆盖索引全文索引修改时间:2026-06-29 11:21:34

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