MySQL——B+tree

来源于小林MySQL中的B+tree

MySql为什么用B+树的结构作为索引

1.I/O速度太慢啦!!!

  • mysql是数据持久化的,索引+数据是存储在磁盘上的,即使设备断电,数据也不会丢失。
  • 磁盘是一个慢的离谱的存储设备,它的读取速度比内存慢几十万倍。
  • 通过索引查找数据的时候,先从磁盘读取索引到内存–>通过索引找到某行数据---->从磁盘把数据读到内存 涉及多次IO 次数越多 时间越大
  • 希望能减少IO操作

2.我们的需求是??

  • 希望索引的数据结构能尽可能在少的IO中完成查询工作。
  • mysql支持范围查找,要高效的查询一条记录,同时也要能高效的执行范围查询。

3.二分查找行不行?

假设用数组来存储索引 二分查找高效定位数据 时间复杂度是O(logn)
每次都把查询范围减半,但是每次都要不断计算中间位置,很烦
而且用数组存索引,每次插入删除都要移动其他的位置,性能太低
在这里插入图片描述

4.二分查找树行不行?

想设计一个天然的适合二分查找的数据结构!二叉树
最中间的结点设置为根节点 左侧比他小 右侧比他大 那么查找的时候直接左走或者右走就行了
而且是一个跳跃结构 插入删除随便搞 不用移动其他
在这里插入图片描述
缺陷在于当每次插入的都是最大的元素,那么一直往右插入,就会形成一个瘸子 只有右腿没有左腿 查找的时候要一直遍历O(N)复杂度还是高

5.那就让二叉树平衡吧

在二叉查找树上加了一些约束,每个节点左子树和右子树高度差不能超过1 每次插入后会自动调整结构,使最终是平衡的。
比如红黑树 通过左旋右旋来达到平衡
缺陷在于:随着插入的元素增多,树的高度会变高,层数高也就意味着IO次数还是多
在这里插入图片描述

6.那就变成M叉树吧 -----B树

分叉增多会让层数变低 降低IO次数 不再限制一个节点只有2个子节点 允许有M>2个节点
在这里插入图片描述
缺陷在于每个节点都包含数据(索引+记录),但是记录数据的大小可能远远超过索引数据 比如想找A 但是检索过程中非A的数据会从磁盘加载到内存,这些没有用,我们只是想读取A的索引作比较而已,其他的只是白白占用内存
如果要范围查找,那么对于范围内的每个值都要中序遍历查找,涉及多个IO,整体速度下降

7.终极解决方案——B+树

在这里插入图片描述

B+和B的结构差异
  • 叶子节点才会存放实际数据(索引+记录)非叶子节点只存在索引(不过会有索引的冗余)
  • 所有索引都会在叶子节点出现,叶子节点之间构成有序链表 。找到一个就能按照链表找到其他,便于范围查询
  • 非叶子节点的索引也会在叶子节点上出现,并且是在子节点中所有索引中最大或者最小
B+和B的性能差异
  • B树在进行单个索引查询时,最快在O(1)就能查询到,但从平均时间代价看B+更快
  • B+树因为非叶子节点没存储记录,所以可以存储更多的索引。B+树更加矮胖,查询底层节点IO次数更少
  • 插入和删除效率高:删除的时候直接从叶子节点删除,甚至可以不动非叶子节点 B树删除节点的时候非常复杂,可能涉及复杂的树的变形 插入同理
  • 所有子节点之间链表连接,对范围查询非常的有效

8.MySql中的B+树

mysql中的默认存储引擎Innodb使用的就是B+树
在这里插入图片描述

总结:为什么MySQL使用B+树作为索引

B+树是一种多叉链表,对于千万级的数据存储只需要3-4层高度就能满足。这意味着查询时最多需要3-4次磁盘I/O。查询效率高。
叶子结点才存放数据,非叶子结点只存放索引。节省空间。而且叶子结点按主键顺序存放,形成双链表,便于范围查询。
存在结点的冗余,对插入和删除操作友好,不太需要变动树的结构。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值