学习笔记:MySQL索引(一)

索引的定义
  • 索引(Index)是帮助MySQL高效获取数据的数据结构。
    注:索引的本质是数据结构。

在开始了解索引之前,我们先简单的了解一下磁盘IO和树的概念。

磁盘IO
  • 磁盘相关的几个概念(以机械硬盘为例):
扇区:磁盘存储的最小单位,扇区一般大小为512Byte
磁盘块:文件系统与磁盘交互的最小单位(计算机系统读写磁盘的最小单位),磁盘块一般大小为4KB
寻道时间:磁臂移动到指定磁道所需要的时间。主流磁盘一般在5ms以下
旋转延迟:磁盘旋转一周所需时间的一半。例:转速为7200转/分,则它的平均旋转延迟为60/7200*0.5≈0.00417s=4.17ms
传输时间:磁盘读写需要的时间。一般零点几毫秒,相较于寻道时间和旋转延迟可以忽略不计
磁盘IO时间:由寻道时间、旋转延迟和传输时间三部分组成
  • 以上述硬盘为例,一次磁盘IO大概需要9毫秒,看似挺快的,如果我们不对数据存储方式做任何优化,假设一张表只存储一个int类型的字段,int占用4Byte,则每个磁盘块可以存储1000条数据,假设数据量为100万,则需要1000个磁盘块来存储。此时我们每次检索都需要读取这1000个磁盘块的数据,一次磁盘IO时间为9毫秒,1000次就是9秒,意味着在百万级数据量的情况下,我们任何一个查询都至少需要9秒。显然这种情况我们是无法接受的。
  • 数据页:页是MySQL中磁盘与内存交互的基本单位,默认是16KB,相当于4个磁盘块。意味着MySQL每读取一次数据就是16KB,这个值由innodb_page_size控制,可以更改。
  • 预读:当发生一次磁盘IO时,不光是读取当前磁盘地址的数据,还会把相邻的数据也读取到内存缓冲区中。
二叉树
二叉树的特点:

1、每个结点包含1个元素及n个子树(0 ≤ n ≤ 2);
2、次序不能颠倒,左子树的元素值 < 父结点的元素值 < 右子树的元素值。

例一:

[4,2,1,3,6,5,7]使用二叉树存储如下:

二叉树

上述树结构检索任何一个数据,最好情况是1次,最坏情况是3次,最坏情况的时间复杂度为O(logN)。

例二:

[1,2,3,4,5,6,7]使用二叉树存储如下:

二叉树退化为链表
可以看到,当我们插入有序的数据时,二叉树便退化成了链表,最坏情况的时间复杂度为O(N)。

二叉树的优缺点:

1、查询效率不稳定,当二叉树结构趋于平衡时,最坏情况的时间复杂度为O(logN);当插入有序数据时,二叉树退化为链表,最坏情况的时间复杂度变成了O(N)。

2、数据量大的情况下,会导致树的高度变高,如果每个结点对应一个磁盘块,那么磁盘IO次数会大量增加,因此用此结构来存储数据是不可取的。

平衡二叉树(AVL树)

平衡二叉树是一种特殊的二叉树,所以拥有上述二叉树的两个特点,除此之外还有一个特性:

平衡二叉树的左右子树高度差的绝对值不超过1。

优缺点:

1、相较于二叉树,平衡二叉树的查询效率比较稳定,不会出现退化成链表的情况;
2、数据量大的情况下,一样会导致磁盘IO次数大量增加,因此也是不可取的。

B树
  • B树是在平衡二叉树上演变而来,平衡二叉树每个结点只能存放一个元素,而B树每个结点可以存放多个元素,主要是为了降低树的高度,减少磁盘IO的次数。
  • B树是一种多路平衡查找树,它的每一个结点最多包含m个孩子,m被称为B树的阶。(m的大小取决于磁盘页的大小)
m阶B树的特点

1、若根节点不是叶子结点,则至少有两个孩子;

2、每个结点最多有m个孩子,m称为B树的阶;

3、每个中间结点都包含k-1个元素和k个孩子,其中(Ceil)m/2 ≤ k ≤ m;

4、每个叶子结点都包含k-1个元素,其中(Ceil)m/2 ≤ k ≤ m;

5、所有的叶子结点都在同一层;

6、每个结点中的元素从小到大排列,结点中的k-1个元素正好是k个孩子包含的元素的值域划分。

如下图(图源自网络)所示为一个3阶B树

3阶B树
如图所示,每个结点占用一个磁盘块,结点中的2个元素划分出三个值域,分别对应3个子树,假设我们要查询数值13,其过程为:

第一次磁盘IO:将磁盘块1读入内存,在内存中定位(与17,35比较);

第二次磁盘IO:将磁盘块2读入内存,在内存中定位(与8,12比较);

第三次磁盘IO:将磁盘块7读入内存,在内存中定位(与13,15比较);

从上述流程不难看出,磁盘IO的次数是由索引树的高度决定的,最坏的情况下,磁盘IO次数等于索引树的高度。B树在查询中的比较次数其实不比二叉查找树少,尤其在单一节点元素数量很多的时候。不过相比于磁盘IO的速度,内存中的比较耗时几乎可以忽略不计,所以只要IO次数足够少(即树的高度足够低),就可以提升查找的性能。

优势:

相较于AVL树,B树通过增加结点的关键字个数来降低树的高度,减少IO的次数。相比之下,结点的内部元素多一点也没有关系,仅仅是多了几次内存的交互,只要不超过磁盘页的大小即可。

缺点:

B树不利于范围查询,比如上图中我们要查询区间[15,36]的数据,需要访问7个磁盘块,所以B树也不太适合在磁盘中存储需要检索的数据。

B+树

B+树结构如图(图源自网络)

B+树结构

  • B+树是基于B树的一种变体,有着比B树更高的查询性能。
m阶B+树的特点

1、有k个子树的中间结点包含k个元素,每个元素不保存数据,只用来索引,所有数据都保存在叶子结点;

2、所有的叶子结点中包含了全量元素的信息,及指向这些元素记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接,形成了一个有序链表;

3、所有的中间结点元素同时存在于子结点,是子结点元素中最大(或最小)的元素。

注:以后无论插入删除多少元素,始终要保持最大(或最小)元素在根结点中。

卫星数据(Satellite Information)

定义:索引元素指向的数据记录,比如数据库中的某一行

B树中的卫星数据:中间结点和叶子结点都带有卫星数据

B+树中的卫星数据:只有叶子结点带有卫星数据,中间结点仅仅是索引,没有数据关联

注:在数据库中的聚集索引(Clustered Index)中,叶子结点直接包含卫星数据。在非聚集索引(NonClustered Index)中,叶子结点带有指向卫星数据的指针。

优点

B+树的优点主要体现在查询性能上:

1、单元素查询时,B+树会自顶而下逐层查找结点,最终找到匹配的叶子结点。

  • 与B树查询的不同点:
    • 首先,B+树中间结点没有卫星数据,所以同样大小的磁盘页能够容纳更多的结点元素。这就意味着在数据量相同的情况下,B+树的结构会比B树更加“矮胖”,查询的IO次数也会更少。
    • 其次,B+树的查询必须最终找到叶子结点;而B树只要找到匹配元素即可,无论是中间结点还是叶子结点。因此,B树的查找性能并不稳定(最好的情况是只查根节点,最坏的情况是查到叶子结点)。而B+树的每一次查询都是稳定的。

2、范围查询时,比如我们要查询3 - 8的元素,

(1)B树只能依靠繁琐的中序遍历;

B树

1、自顶向下,查找到范围的下限3

2、中序遍历到元素4

3、中序遍历到元素5

4、中序遍历到元素6

5、中序遍历到元素8,遍历结束

(2)B+树只需要在链表上做遍历即可。

B+树

1、自顶向下,查找到范围的下限3

2、通过链表指针,遍历到元素5,6

3、通过链表指针遍历到元素8,遍历结束

综上所述,B+树相比于B树的优势有三:

  • 单一结点存储更多元素,使得查询的IO次数更少;
  • 所有查询都要查找到叶子结点,查询性能稳定;
  • 所有叶子结点形成有序链表,便于范围查询。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_秋牧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值