从B+树角度解释LIKE查询的索引使用

ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花

要理解LIKE查询如何使用B+树索引,首先需明确两个核心前提:一是B+树索引的本质的是“有序的平衡树结构”,其索引键按字典序排列,叶子节点存储完整索引键(或行指针)并形成有序链表;二是LIKE查询的核心是“模糊匹配”,不同匹配模式(前缀、后缀、中间匹配)对索引的利用程度,完全取决于是否能借助B+树的“有序性”快速定位匹配范围。

一、B+树索引的核心特性(为LIKE查询铺垫)

B+树索引的核心价值的是“有序性”和“快速范围查找”,关键特性如下:

  • 索引键按字典序(如字母顺序、数字顺序)逐层排序,非叶子节点存储索引键的中间值,用于引导查找方向,实现二分查找级别的高效定位;
  • 所有叶子节点通过指针串联成有序链表,便于范围遍历(这是LIKE前缀匹配能高效使用索引的关键);
  • 索引查询的核心逻辑:先通过非叶子节点定位到“匹配范围的起始位置”,再通过叶子节点的链表遍历,获取所有符合范围的记录,避免全表扫描。

二、不同LIKE匹配模式的索引使用情况(结合B+树原理)

LIKE查询的匹配模式主要分为3类,其索引使用差异的核心,在于“是否能确定B+树中的查找范围”,以下逐一分析:

1. 前缀匹配(如 LIKE 'abc%'):能高效利用B+树索引

这是唯一能充分利用B+树索引的LIKE匹配模式,核心原因是“前缀固定”,可借助B+树的有序性定位明确的查找范围。

具体过程(结合B+树结构):

  1. B+树的索引键按字典序排列,例如索引键为['abc123', 'abc456', 'abd789', 'ace000'],当查询条件为 LIKE 'abc%'时,“abc”是固定前缀,匹配的索引键必须以“abc”开头;
  2. 数据库通过B+树的非叶子节点,二分查找定位到“abc”对应的最小索引键(如'abc123'),这是匹配范围的起始位置;
  3. 借助叶子节点的有序链表,从起始位置开始向后遍历,直到遇到不满足“以abc开头”的索引键(如'abd789'),停止遍历;
  4. 遍历过程中,通过叶子节点存储的行指针,快速定位到对应的数据行,无需扫描全表。

补充:前缀匹配的效率接近等值查询,遍历范围仅为“前缀相同的索引键”,B+树的有序性和链表结构完全发挥作用,是最推荐的模糊查询方式。

2. 后缀匹配(如 LIKE '%abc'):无法利用B+树索引(默认情况)

后缀匹配无法利用B+树索引,核心原因是“后缀固定但前缀不确定”,无法在B+树中定位明确的查找范围。

具体分析(结合B+树结构):

B+树的索引键排序是“从左到右”的字典序,例如索引键['aabc', 'babc', 'cabc', 'abcd'],查询条件为 LIKE '%abc'时,匹配的索引键结尾是“abc”,但前缀可以是任意字符(a、b、c等)。

由于B+树无法根据“后缀”反向定位起始范围——非叶子节点的中间值只能引导“从左到右”的查找,无法判断“哪些索引键的结尾是abc”,因此只能放弃索引,执行全表扫描,逐一判断每条记录是否满足后缀匹配条件。

例外情况:若对字段进行“反向存储”(如将'abc123'存储为'321cba'),并建立反向索引,此时后缀匹配可转化为前缀匹配(LIKE '%abc' 转化为 LIKE 'cba%'),就能利用B+树索引,但这种方式需额外维护反向字段,实用性有限。

3. 中间匹配(如 LIKE '%abc%'):无法利用B+树索引(默认情况)

中间匹配的模糊程度最高,前缀和后缀均不确定,完全无法借助B+树的有序性定位查找范围,因此默认只能执行全表扫描。

具体分析(结合B+树结构):

例如查询 LIKE '%abc%',匹配的索引键中包含“abc”即可,可能出现在开头、中间、结尾(如'abc123'、'xabcx'、'123abc')。由于B+树的有序性是“整体字典序”,无法筛选出“包含特定子串”的索引键范围——非叶子节点无法引导查找,叶子节点的链表遍历也需要扫描所有节点,与全表扫描效率差异不大,因此数据库会直接选择全表扫描。

三、关键总结(B+树与LIKE查询的核心关联)

LIKE查询能否使用B+树索引,本质是“能否通过匹配模式,在B+树中确定明确的查找范围”,核心结论如下:

  • 只有前缀匹配('abc%')能利用B+树索引,核心依赖B+树的“有序性”定位起始范围,再通过叶子节点链表遍历匹配记录;
  • 后缀匹配('%abc')、中间匹配('%abc%'),因无法确定B+树中的查找范围,默认无法利用索引,只能全表扫描;
  • B+树索引的“有序性”是前提,任何破坏“前缀确定性”的匹配模式,都会导致索引失效——因为B+树无法反向或无序查找。

ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花

MySQL存储引擎与索引 文章被收录于专栏

还在纠结MySQL存储引擎怎么选?选错直接拉垮系统性能!MySQL插件式存储引擎架构适配多元业务:InnoDB(默认)支持事务、行级锁,扛高并发OLTP场景;MyISAM查询快无事务,适配读多写少场景;Memory读写极速但无持久化,适合临时缓存;Archive高压缩归档日志,CSV便捷跨系统交互,NDB支撑分布式集群。本期专栏拆解各引擎核心特性与选型逻辑,教你选对引擎,让数据库性能拉满!

全部评论

相关推荐

昨天 17:28
南京大学 Java
1. 代码考核题1:找出长度最小的子数组2. 代码考核题2:SQL题目,涉及两张表连接、按日期分组计算人均PV3. 请做一个自我介绍4. 你的项目是学校课程作业还是自己学习的?具体介绍一下项目来源5. 你的商城项目考虑了高并发,说一下整体架构设计思路6. 说一下你的部署方案7. 解释一下JWT + Redis双token机制的工作原理,以及相比传统session登录的优势8. Redis有几种数据结构,各种数据结构的特点和优缺点是什么?9. 为什么使用Redis + Lua脚本来扣减库存?10. 在Lua脚本里面怎么定义一个变量?11. 订单和库存的数据一致性是怎么保证的?是什么级别的一致性(最终一致性还是实时一致性)?12. 多级缓存(Caffeine + Redis)架构存在哪些问题?分布式部署时又会遇到什么问题?13. 订单智能释放使用了RocketMQ延迟消息+定时任务兜底方案,为什么不能只用RocketMQ延迟消息?14. 如果项目运行中接口突然变慢,怎么去查找问题所在并解决?15. 你的Agent项目是怎么做的?有没有知识库训练?16. 意图判断和意图识别是怎么处理的?17. prompt是谁写的?是内置的还是用户自己写?18. 你们有统一的家居行业知识库吗?是给大模型提前训练还是有现成的针对家居的抓手大模型?19. 你是怎么使用AI coding的?第一次面试,准备得很不充分,刚上来就是代码题有点紧张。面试官是s3的,难道技术提前批都是去s3?感觉基本寄了,上来直接问部署细节(我本来想答K8s,docker之类的但不熟就没说)+ 语法细节,很明显就知道项目不是我从头到尾自己手搓的(我说用了AI coding)没有问八股(很奇怪),一直在拷打项目,答得整体一般
点赞 评论 收藏
分享
03-08 16:30
门头沟学院 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务