MSQL系列(三) Mysql实战-索引最左侧匹配原则原理

Mysql实战-索引最左侧匹配原则原理

前面我们讲解了索引的存储结构,我们知道了B+Tree的索引结构,索引的叶子节点是严格排序的,就像你看到的 底层叶子节点 15->18->20->30->49->50等等
这样做有什么好处呢? 这就引出了我们今天要讲的索引最左侧匹配原则
在这里插入图片描述

1.叶子节点排序

经过上图,我们知道叶子节点是严格排序的,B+Tree的叶子节点有以下特点

  • 每个节点内部,数据大小都是从左到右依次递增的
  • 每个节点对应的左边子节点一定是小于等于自己的
  • 每个节点右边子节点也一定是大于等于自己的数据

这样设计的原因是什么呢?我们想一下如果要查找数据60,我们应该如何查找?

  • 第一步 顶层节点, 60 > 35 , 找35的右子树
  • 第二步 中间节点, 60 < 65, 找65的左子树
  • 第三步 从左往右找,36,60, 定位元素

单元素很快就能定位到问题, 但是日常项目中,我们一般都是用 联合索引,不是唯一键索引,所以下面的叶子节点是多个,多个的情况下,联合索引 如何查找数据?

2.索引查找匹配逻辑

我们现在存储了一些字符串,如下面 aa,ad,ca,da,gh,ik 大家可以看到

  • 叶子节点,每个字符串的首字符 a,c,d,g,i 来看,是有顺序的
  • 从上到下 左子树 ca,ad,aa 首字符 c,a,a 也是有序的
  • 是一个标准的二叉树

如果我们有以下的查询语句,查找字符串中包含d的数据, 会如何查找

select * from table where data like "%d";

在这里插入图片描述

按照之前单节点的逻辑,只需要定位到左右子树,查找就行,我们来试一试, 查找第二个字母为 d的目标数据

  • 顶层字符是ca, 第二个字符是a
  • 现在查找 %d,d字符, d字符>a字符,应该往右子树查找 da,gh
  • da和gh的两个节点,第二个字符是a,h,刚好 a<d<h, 所以应该在da右子树,gh左子树
  • 往下找,找到三层叶子节点da
  • 我们要找的是 第二个字符是 d的,结果现在定位到了 da,不是我们要的结果

原本的排序策略没用了

那如果是查询语句换成下面的呢?查找以a开头的数据

select * from table where data like "a%";

还是用刚才的逻辑,我们来看下,依旧是查找第一个字符是a的数据

  • 顶层节点ca,第一个字符c,比 a大, 所以找他的左子树
  • 左子树找到了二层ad,第一个字符是a, B+Tree的规则 左节点小于,等于当前节点,找左右节点
  • 左右节点,找到了 aa,ad,全都满足要求,返回数据

说明索引有效,说到这里,大家是否明白了 什么是 最左匹配原则?

3.最左匹配原则原理

上面的例子 就是我们的抛砖引玉的过程,说明必须用 左侧数据作为索引基准数据,这种就叫做最左侧匹配原则

下面我们使用组合索引,来介绍以下 最左侧匹配原则 ,我们都知道索引的底层是一颗 B+ 树,那么联合索引呢?

  • 联合索引依旧是一颗 B+ 树,只不过联合索引的键值数量不是一个,而是多个
  • 构建一颗 B+ 树只能根据一个值来构建,因此数据库依据联合索引最左的字段来构建 B+ 树
  • 假如创建一个(a,b,c) 的联合索引,下图就是一个形如(a,b,c)联合索引的 b+ 树
  • 其中的非叶子节点存储的是第一个关键字的索引 a,叶子节点存储的是三个关键字的数据
  • 这里可以看出 a 是有序的,而 b,c 都是无序的
  • 而且顺序依次传递,在 a 相同的时候,b 是有序的,b 相同的时候,c 又是有序的
  • 这样的联合索引结构,可以很好的解释为什么最左匹配原则,如果查询语句是范围查找就会停止
  • 因为无法根据b决定c的顺序,只有b相同的时候c才是有序的,无法继续按顺序查找

查询语句

select * from t where a=5 and b>0 and c =1; 
  • 当查询到 b 的值以后(这是一个范围值),c 是无序的。所以就不能根据联合索引来确定到底应该取哪一行的数据,进行继续查找
    在这里插入图片描述

了解了索引底层的存储结构,我们就能明白最左侧匹配原则的原理,这有利于我们在创建索引的时候,尽可能的优化索引,避免索引失效的场景

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL索引的最左匹配原则是指在使用复合索引进行查询时,必须按照索引的最左边的列开始匹配,然后再逐个匹配剩余的列。如果不按照索引的最左边的列进行匹配MySQL将无法利用索引,而需要进行全表扫描,对性能会产生很大的影响。\[1\]\[2\]\[3\] 举个例子,如果有一个由(a, b, c)组成的复合索引,那么在查询时必须先使用a进行过滤,然后才能使用b或c进行过滤,即使b或c也属于索引的一部分。如果不按照这个顺序进行查询,MySQL将无法使用索引进行优化。\[3\] 需要注意的是,最左前缀匹配原则只适用于联合索引,而不适用于单列索引。在建立联合索引时,最左前缀匹配原则可以帮助我们优化查询性能,提高查询效率。\[2\] #### 引用[.reference_title] - *1* *3* [MySQL的最左匹配原则](https://blog.csdn.net/weixin_52060913/article/details/130615245)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Mysql 联合索引左匹配原则](https://blog.csdn.net/Klaus_S/article/details/130972214)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值