绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
B+树索引使用(7)匹配列前缀,匹配值范围(十九)
2023-01-30 14:58:58

上篇文章索引的代价,b+树占的空间比较大,增删改对b+树每个节点的索引排序影响也很大,事件耗费长,所以没有必要不要乱建索引,还介绍了索引的左原则和全值查询。

匹配列前缀

innoDB给其他列添加二级索引,会按列给他排序,不管是页之间的双向链表排序,还是页内数据槽点的单向列表排序,都是按列值排的。比如name列,如果名字有TOM,Anny,Aone等,1)先按首字母给他排序。2)首字母都是A一样,则按第二个字母给他排序。3)依次类推,一样就用后面一直给他排序。所以我们用模糊查询的时候where name like ‘a%’;这种百分比号放在后面是可以触发索引查询的,但若是where name like ‘%a’;这种因为个字母找不到,这种没有排序好,导致只能全盘扫描,放弃索引查询。

举个例子,当我们有字段列url,分别有数据,www.baidu.com,www.google,www.gov.com,www.wto.com。

这时候我们想查询com结尾的,如果用where url like ‘%com’;则效率会非常低,无法触发索引查询。那我们为了提高效率,用索引来查询数据,可以先把表的数据逆排序一下,改为,moc.udiab.www,moc.elgoog.www,nc.vog.www,gro.otw.www,这时候就可以用where url like ‘com%’;来触发索引查询。

匹配值范围

我们看idx_name_birthday_phone索引b+示意图,所有记录都是按索引从小到大进行排序的,比如我们用where name > ‘Anny’ and name < ‘barlow’;所以这个查询过程:1)先在b+树叶子节点找到name值大于Anny的二级索引记录,读取主键,在用聚簇索引进行回表查询操作,获取聚簇索引的全部用户记录数据后发给客户端。2)根据上一步找到的记录,沿着所在的链表位子(页之间双向链表关联,页内数据,单向链表关联)查找下一条二级索引记录,判断该记录是否<barlow,如果符合,则返回给客户端。3)重复2的操作,直到不符合。

所以,这时候会使用索引查询的,但重点需要注意,注意,注意(重要的事要说三遍):如果对多个列进行范围查询,只有索引左边的那个列查询时候会使用到b+树的索引进行查询。

比如where name > ‘Anny’ and name < ‘barlow’and birthday > ‘1990-01-01’;这时候查询过程:1)和前面说的一样,先name在b+树叶子节点找到列>Anny的主键,用主键查询聚簇索引的树回表操作,查询完之后,在查询下一个是否满足<barlow。2)对于上面name不同的值,在进行birhday进行birthday>’1990-01-01’过滤。

这样查询对于联合索引来说,只会name的时候用到了索引排序,而因为biryhday排序的条件是需要先name排序相同才会排序,此刻获取的name都是不同的,所以在birthday范围查询的时候无法触发索引。

到某一列,范围另外一列

当我们用where name = ‘Anny’ and birthday > ‘1990-01-01’ and phone > ‘13200000000’;这时候我们查询过程就是:1)name肯定使用b+树的二级索引先查询到叶子节点的列值加主键,再聚簇索引回表操作返回聚簇索引叶子节点的全部数据。2)因为name相同的情况下,birthday会触发索引查询,先在b+树叶子节点找到>’1990-01-01’的列值和主键,在通过主键回表查询全部数据3)因为phone使用索引查询的前提是birthday相同,而前面的是不同的birthday,索引phone不能使用索引查询。


文章来源:知乎平台 原文地址:https://zhuanlan.zhihu.com/p/403531069

分享好友

分享这个小栈给你的朋友们,一起进步吧。

MySQL干货资料
创建时间:2020-05-06 14:18:32
每天都有干货输出哦
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

技术专家

查看更多
  • 飘絮絮絮丶
    专家
戳我,来吐槽~