Mysql索引之B+树

1 索引的常见模型

索引是一种能够提升查找效率的数据结构,提到查找,作为一名合格程序员首先就应想到哈希表、有序数组和二叉查找树(AVL树、红黑树)。接下来从数据库的使用角度来对这三种数据结构进行分析。

1)哈希表

哈希表是一种利用键值对(key-value)访问数据的一种结构。哈希表是一块连续的存储空间,利用哈希函数计算出key在表中的具体地址,随后将value插入到这个地址中。在查找数据时,根据键值对应的地址去除数据即可。

选取哈希函数的原则:
(1)计算简单
(2)计算出的地址在表中尽可能均匀分布

然而有可能多个key通过计算后的地址是相同的,这种情况我们称之为“哈希冲突”。解决哈希冲突的一种重要方法是,在冲突的地址上拉出一个链表,冲突的关键字依次连接于该链表上,如下图所示:
在这里插入图片描述
简单介绍过哈希表过,可发现哈希表的查找时间复杂度为O(1),但与此对应的缺点是因为键值在哈希表中的存储不是有序的,即在进行区间查找时速度会很慢。即这种结构适用于等值查找的场景。

2)有序数组

可将有序数组看作时一个另类的哈希表,即表中的键值是按序排列的,这样保正了在等值查找和区间查找时的复杂度都为O(1)。但是在数据插入时,需要移动插入位置后的所有巨鹿,成本过高。

3)二叉查找树

无论是AVL树还是红黑树在插入和查找时的时间复杂度均为O(logn),好似满足我们的要求,但是数据库中的数据是保存在磁盘上,并不是保存在内存中。假设一颗AVL树的高度为100,若需要查找的数据位于叶子结点,就会访问100个数据块,每次深度加1就会进行一次磁盘IO的查询,磁盘I/O是很耗费时间的,为了减少磁盘I/O的次数,就需要在查询的过程中访问尽量少的数据块,即需要降低查找树的高度,将二叉树变为"N"叉树,"N"取决于数据块的大小,而B+树正是这样一种"N"叉树。

2 B树与B+树

1)B树

B树是一种平衡的多路查找树,查找的时间复杂度为O(logn)。B树的每个结点既包含关键字又包含存储数据信息,如图所示。
在这里插入图片描述
一个度为d的B树,设节点为数N,则其树高h的上限为logd((N+1)/2),检索一个值,其查找节点个数的时间复杂度为O(logdN)。这样使得在B树中检索一个节点最多需要h个节点,而数据库系统中一般将一个节点的大小设定为一个页,每个节点一次IO。使B树的根节点常驻内存,则一次检索最多需要h-1次的I/O即可。

2)B+树

与B树相同,B+树也是一颗多路查找树,但不同于B树的是:
(1)B+树中只有叶子结点包含数据信息并包含了全部关键字,叶子结点引出的指针指向记录。B+树中所有非叶子结点仅仅起到一个索引的作用,即结点中的每个索引项只包含关键字与指向子树的指针,不包含关键字对应记录的存储地址。简单来说,B+树只有叶子结点存放存储的数据信息。
(2)B+树上有两个头指针,一个指向根节点,另一个指向关键字最小的叶子节点,叶子结点本身依关键字的大小自小而大的顺序链接。所以B+树有两种查找数据的方式,一种从根节点自上而下的进行查找,而另一种就是通过由叶子结点组成的链表进行查找。
在这里插入图片描述
在计算机中,磁盘存储数据最小单元是扇区,一个扇区的大小是512字节,而文件系统(例如XFS/EXT4)的最小单元是块,一个块的大小是4k,而对于InnoDB存储引擎也有自己的最小储存单元,页(Page),一个页的大小是16K。B+树的叶子结点正是以页为单位进行存储。

3 为什么mysql使用B+树作为索引而不是B树

1)B+树的磁盘读写代价更低
  B+树的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B 树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了;
2)B+树查询效率更加稳定
  由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当;
3)B+树便于范围查询(最重要的原因,范围查找是数据库的常态)
  B树在提高了IO性能的同时并没有解决元素遍历的我效率低下的问题,正是为了解决这个问题,B+树应用而生。B+树只需要去遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作或者说效率太低;B树的范围查找是利用中序遍历实现的,而B+树则是利用链表实现的。

(文中图片来源自网络,侵删)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值