MySQL索引结构,为何选用B+树,悟了

以下文章来源于小龙coding ,作者小龙coding

如有侵权,联系删除

不少同学私信,问其面试常问的一个经典问题:"MySQL 索引为何选用 B+ 树" 思路远比结论重要,今天简单聊聊索引为何这样设计?

何为索引:以图书馆为例,需借助检索目录,以加快书本查询定位;同理,MySQL索引也即为排好序的一种数据结构,用于提升数据库的查找速度。

哈希(hash)比树(tree)更快,索引结构为什么要设计成树型?

知其然,知其所以然。分析两种数据结构时间复杂度:

(1)哈希(Hash)结构,例如 HashMap查询、删除、插入、修改的平均时间复杂度都是 O(1);

(2)树(tree)结构,例如平衡二叉搜索树,查询、删除、插入、修改 的平均时间复杂度都是 O(logN) ;

从中分析可见,若用 Hash 类型的索引结构,无论是在读请求,还是写请求,都比 树(tree)类型的索引结构快;、

那,为何 MySQL 索引结构还设计成树型结构呢?

其一:若是简单的读写请求,Hash结构效果当然更佳;Hash 底层采用哈希表实现,等值查询,可以快速定位,一般情况效率很高。但也不稳定,当出现大量键重复哈希冲突,效率下降。

其二:MySQL 需要满足更多场景的 SQL 查询需求。Hash不支持范围查询,无法用于排序分组(grou by),无法模糊查询(like %),多列索引的最左前缀匹配原则。

而在众多树之中,MySQL最后选择了改进后的B树—>B+树

那,MySQL 索引为什么使用 B+ 树呢?而不用 B 树、红黑树?

你事先需要知道的几种树:

二叉搜索树

(1)当数据量大的时候,树的高度会比较高,数据量大的时候,查询会比较慢

(2)当数据线性增大时,二叉搜索树会呈现单边倒的情况,时间复杂度退化 O(n),效率更低

(3)每个节点只存储一个记录,可能导致一次查询有很多次磁盘IO

图片

AVL 树(平衡二叉搜索树)

平衡树虽然可以弥补 "当数据线性增大时,二叉搜索树会呈现单边倒的情况,时间复杂度退化 O(n) 的情况”,但是他还是具有二叉搜索树一样的缺点。

图片

B树

B树,如下图,它的特点是:

(1)不再是二叉搜索,而是 m 叉搜索(可以根据不同度数分裂),而正由于是 m 分叉的,高度能够大大降低;

(2)并且 B树 叶子节点、非叶子节点,都可以存储数据;如果将每个节点大小设置为页大小,那么利用磁盘预读的特性,可以极大减少磁盘IO;并且,通过中序遍历,可以很快找到节点对应的数据

思考:那到了 B 树结构,直接用来做索引是否就完美了呢?

虽然 B 树相对其他种树优势很明显,但是在范围查询时,还是很吃力;想要减少磁盘IO,节点最好设置为页大小,节点(页)大小固定后,若每个节点都存数据,每个节点也存不下多少,数据大时树的高度也不低

于是,B+ 树应运而生,在B树上做小小改动,便是目前完美的索引结构啦。

图片

B+树

B+树,如下图,仍是 m 叉搜索树。在 B树 的基础上,进行了一些改进

(1)非叶子结点不存data,只存key,查询更稳定,增大了广度;数据只存在叶子节点;

(2)叶子之间,增加了链表。可以很好的支持范围查询,并且获取所有节点,不再需要中序遍历;

相比 B树 具有更优的特性:

(1)范围查找,定位min与max之后,中间叶子节点,就是结果集啦;

(2)叶子节点存储实际记录行,记录行相对比较紧密的存储,适合大数据量磁盘存储;非叶子节点存储记录的PK(KEY数据小,相同内存情况下,节点可以多存KEY,增大了节点广度(B+树出度更大,进而树高更矮,磁盘IO次数更少))用于查询加速,适合内存存储;

图片

总结:

  1. 索引为排好序的一种数据结构,用于提升数据库的查找速度。

  2. Hash索引时间复杂度为O(1),树索引是O(log(n))。Hash 底层是哈希表实现,等值查询,可以快速定位数据。但不支持范围查询,无法用于排序分组,无法模糊查询等操作。

  3. B+树作为索引优势:

    • 叶子节点存储实际记录行,记录行相对比较紧密的存储,适合大数据量磁盘存储;

    • 非叶子节点存储记录的PK(KEY数据小,相同内存情况下,节点可以多存KEY,增大了节点广度(B+树出度更大,进而树高更矮,磁盘IO次数更少))用于查询加速,适合内存存储;

    • 叶子之间,增加了链表。可以很好的支持范围查询,并且获取所有节点,不再需要中序遍历;

    • 更少查询次数:B+树出度更大,树高更低,查询次数更少;

    • 很适合磁盘存储,能够充分利用局部性原理,磁盘预读(为了减少IO操作,往往不严格按需读取,而是预读。B+树叶子结点存储相临读取会快一些

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值