B+树索引(3)之索引推导优化

B+树索引(3)之索引推导优化

前言回顾

在之前的文章中提到一个简单索引的原理,文章可以参考

B+树索引(2)之索引的推导

其中采用给数据页建立目录的方法解决了多个数据页需要遍历查询的问题,提升了查询效率,如图所示图片

但是这个方法有个默认前提是所有的目录项需要在同一片连续的空间,在现实中显然是不可能的,原因有两点

  • 随着表数据量的增大,数据页会明显增加而目录项也会跟着增加,需要的空间只会越来越大。

  • 如果某个数据页被删除,那么对应的目录项也需要删除,这并不是关键,关键的是被删除的目录项后面的目录项也需要和向前移动,这显然十分消耗性能。

基于这两点上面的索引方案显然是要改进。

索引方案改进

既然目录项需要排序,而且目录项的值固定是页号和数据页最小主键值,那为什么不能采用数据页进行存储呢!这样并不需要分配空间的连续性因为记录头中存在next_record属性,删除页只需要改动next_record指向的值即可,显然这个方案可行。

但是我们需要注意的是如何区分是目录项的记录还是业务数据的记录呢?这里就需要回到之前聊过记录头的一个属性record_type,之前说过这个属性的值有4个,如下所示

  • 0:业务数据记录。

  • 1:目录项记录。

  • 2:最小记录。

  • 3:最大记录。

知道这个后我们就可以将数据页的索引结构优化,如下

图片

普通的业务数据记录页和目录项记录相差不大,主要有如下几点区别。

  • 普通业务数据记录页的记录头record_type=0,而目录项的为record_type=1。

  • 普通业务数据记录页存在隐藏列和用户自定义列,而目录项只有两个列(数据页最小主键值和数据页页号)。

  • 在存储目录项的数据页中最小主键值的记录头中min_rec_mask属性为1,其余都为0。

这样存储的好处就是不需要大片的连续空间,查询时分为两个步骤

  • 根据主键值通过二分法在目录项数据页中定位到记录需要在哪一个数据页中。

  • 根据主键值通过二分法定位单个数据页中的记录。

这样查询确实省事,但问题又回到原点,之前就是因为数据页之间无规律,才导致需要遍历所有的数据页,虽然这里通过目录项数据页可以实现简单寻找,但如果目录项数据页也存在多个,这时不还需要遍历吗?

假设一个存放目录项的数据页一次最多存放四条记录,如果超出四条需要再申请一个数据页存放目录项,如下所示

图片

上图中的页30和页32都是目录项数据页,同样会需要遍历多个数据页的情况,这时候如何解决呢?既然都是数据页那么同样给页30和页32建立一个目录项数据页,所以上图就演化为如下所示

图片

比如我想查询主键为15的记录项,那就非常简单了,步骤如下

  • 根据主键值在数据页35中直接定位到下一步需要查找的数据页为页30因为(1 < 15 < 27)

  • 在页30中同样定位到数据页应该是在页19因为(12 < 15 < 21)。

  • 在页19中再根据主键值去页目录中继续查找得到最终结果。

这样的组织结构有一个专业名词就被称为B+树

B+树介绍

在B+树中我们将这些数据页称为节点,我们可以从上图中看出所有的业务数据只会存储到树的最底层,这些节点被称为叶子节点,而剩余的目录项数据页被称为非叶子节点,最顶层的数据页被称为根节点

不知道大家有没有这种疑问,B+树遍历数据页的次数就是树的高度,也就是树越高需要遍历数据页的次数就越多,这样是不是也会影响查询速度呢?这样直接看文字肯定是合理的,但我们可以做一个简单的分析。

之前为了方便画图假设的是存储业务记录的数据页最多存储3条记录,存储目录项的数据页最多存储4条记录,而真实情况这个数据量是非常大的,为了方便统计再次假设存储业务记录的数据页最多存储100条记录,存储目录项的数据页最多存储1000条记录

  • 当B+树只有一层时,只有一个数据页也就是最多存储100条记录。

  • 当B+树只有两层时,可以存放记录数是1000 * 100。

  • 当B+数只有三层时,可以存放记录数是1000 * 1000 * 100。

  • 当B+数只有四层时,可以存放记录数是1000 * 1000 * 1000 *100。

在现实情况下,一个表存储的数据量还是有限的,我们用到的B+数索引不会超过四层,所以并不用去担心B+树的高度问题,采用B+树结合二分法定位数据是非常快的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值