B+树索引及其使用

一、B+树索引

各个数据页组成双向链表,每个数据页中的记录会按照主键值从小到大的顺序组成一个单向链表。
在这里插入图片描述

1.1 没有索引时进行查找

假设搜索条件为某个列等于某个常数的情况:

SELECT [查询列表] FROM 表名 WHERE 列名 = xxx;

(1)若此时只有一个页,根据搜索条件不同分为两种情况:

  • 以主键为搜索条件:在页目录中使用二分法定位到对应的槽,然后再遍历该槽对应分组中的记录,即可定位指定记录
  • 以其他列为搜索条件:数据页中并没有为非主键列建立页目录,所以只能从Infinum记录开始依次遍历

(2)若有很多数据页,此时需要首先沿着双向链表一页一页地根据情况(1)确定此页有没有目标记录,时间复杂度极高。

于是需要一种高效完成搜索的方法——索引。

1.2 索引

先建个表:
在这里插入图片描述
其对应的行格式示意图:
在这里插入图片描述在这里插入图片描述

关于行格式及相关字段含义参照文章:
https://blog.csdn.net/sunximei/article/details/121249738

1.3 一个简单的索引方案

我们的第一个需求就是快速定位一个记录所在的数据页。想到在一个页中根据主键值定位记录采用的页目录方法,我们也可以为数据页建立一个别的目录。
在建立此目录的过程中需完成两件事:

1. 下一个数据页中的记录主键值需大于上一页中的。
假设每页最多只能存放3条记录。首先向index_demo表插入3条记录:

INSERT INTO index_demo VALUES (1, 4, 'u'), (3, 9, 'd'), (5, 3, 'y');

在这里插入图片描述
此时再插入一条记录:

INSERT INTO index_demo VALUES (4, 4, 'a');

由于记录数超过页最大容量,于是分配新页。但为了使得新页中的主键值大于旧页,所以需要将主键值为5的记录移动至新页,然后再将主键值为4的记录插入旧页。这个过程也可称为页分裂。
在这里插入图片描述
注:新分配的页编号可能不是连续的,即在磁盘上并不相邻(不过InnoDB设计尽量让其相邻)

2. 给所有的页建立一个目录项
模拟向表中插入多条记录的效果:
在这里插入图片描述
由于这些大小为16KB的页在磁盘上并不相邻,所以需要为所有的页编制一个目录,每个页对应一个目录项,每个目录项包括两个部分:

  • 页中用户记录的最小主键值key
  • 页号page_no

效果如图:
在这里插入图片描述
然后将这些目录项在存储器上连续存储(如数组),就可以实现根据主键值快速查找记录(两次二分法)。这个目录就被称为索引。

1.4 InnoDB的索引方案

刚才的简易方案是基于所有目录项都可以在存储器上连续存储的前提下,实际上存在一些问题:

  • InnoDB使用页作为管理存储单位的基本单位,即最多保证16KB连续存储空间。所以无法应对过多的目录项
  • 执行删除操作时,会导致被删除项后的所有记录都前移,时间复杂度高;若作为冗余留在页
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值