众所周知,MySQL的索引使用了B+树的数据结构。那么为什么不用B树呢?

先看一下B树和B+树的区别。

B树

维基百科对B树的定义为“在计算机科学中,B树(B-tree)是一种树状数据结构,它能够存储数据、对其进行排序并允许以O(log n)的时间复杂度运行进行查找、顺序读取、插入和删除的数据结构。B树,概括来说是一个节点可以拥有多于2个子节点的二叉查找树。与自平衡二叉查找树不同,B-树为系统最优化大块数据的读和写操作。B-tree算法减少定位记录时所经历的中间过程,从而加快存取速度。普遍运用在数据库和文件系统。”

B 树可以看作是对2-3查找树的一种扩展,即他允许每个节点有M-1个子节点。

定义

  • 根节点至少有两个子节点
  • 每个节点有M-1个key,并且以升序排列
  • 位于M-1和M key的子节点的值位于M-1 和M key对应的Value之间
  • 其它节点至少有M/2个子节点

下图是一个M=4 阶的B树:

可以看到B树是2-3树的一种扩展,他允许一个节点有多于2个的元素。

B树的插入及平衡化操作和2-3树很相似,这里就不介绍了。

B+树

B+树是对B树的一种变形树,它与B树的差异在于:

  • 有k个子结点的结点必然有k个关键码。
  • 非叶结点仅具有索引作用,跟记录有关的信息均存放在叶结点中。
  • 树的所有叶结点构成一个有序链表,可以按照关键码排序的次序遍历全部记录。

如下图是一个B+树:

B+树和B树的区别

B+树的非叶子结点只包含导航信息,不包含实际的值,所有的叶子结点和相连的节点使用链表相连,便于区间查找和遍历。

B+ 树的优点在于:

  • IO次数更少:由于B+树在内部节点上不包含数据信息,因此在内存页中能够存放更多的key。 数据存放的更加紧密,具有更好的空间局部性。因此访问叶子节点上关联的数据也具有更好的缓存命中率。
  • 遍历更加方便:B+树的叶子结点都是相链的,因此对整棵树的遍历只需要一次线性遍历叶子结点即可。而且由于数据顺序排列并且相连,所以便于区间查找和搜索。而B树则需要进行每一层的递归遍历。相邻的元素可能在内存中不相邻,所以缓存命中性没有B+树好。

但是B树也有优点,其优点在于,由于B树的每一个节点都包含key和value,因此经常访问的元素可能离根节点更近,因此访问也更迅速。

下面是B 树和B+树的区别图:

为什么MySQL选择B+树做索引

  • B+树的磁盘读写代价更低:B+树的内部节点并没有指向关键字具体信息的指针,因此其内部节点相对B树更小,如果把所有同一内部节点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多,一次性读入内存的需要查找的关键字也就越多,相对IO读写次数就降低了。

  • B+树的查询效率更加稳定:由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

  • B+树更便于遍历:由于B+树的数据都存储在叶子结点中,分支结点均为索引,方便扫库,只需要扫一遍叶子结点即可,但是B树因为其分支结点同样存储着数据,我们要找到具体的数据,需要进行一次中序遍历按序来扫,所以B+树更加适合在区间查询的情况,所以通常B+树用于数据库索引。

  • B+树更适合基于范围的查询:B树在提高了IO性能的同时并没有解决元素遍历的我效率低下的问题,正是为了解决这个问题,B+树应用而生。B+树只需要去遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作或者说效率太低。

MySQL用B+树(而不是B树)做索引的原因的更多相关文章

  1. 数据库为什么使用B+树而不是B树

    B树和B+树的区别主要有两点: 在B树中,你可以将键和值存放在内部节点和叶子节点,但在B+树中,内部节点都是键,没有值.叶子节点同时存放键和值 B+树的叶子节点有一条链相连,而B+树的叶子节点各自独立 ...

  2. mysql的索引为什么要使用B+树而不是其他树?

    总结 1.InnoDB存储引擎的最小存储单元是页,页可以用于存放数据也可以用于存放键值+指针,在B+树中叶子节点存放数据,非叶子节点存放键值+指针. 2.索引组织表通过非叶子节点的二分查找法以及指针确 ...

  3. 为什么用B+树做索引&MySQL存储引擎简介

    索引的数据结构 为什么不是二叉树,红黑树什么的呢? 首先,一般来说,索引本身也很大,不可能全部存在内存中,因此索引往往以索引文件的方式存在磁盘上.然后一般一个结点一个磁盘块,也就是读一个结点要进行一次 ...

  4. 为什么 MySQL 索引要使用 B+树而不是其它树形结构?比如 B 树?

    一个问题? InnoDB一棵B+树可以存放多少行数据?这个问题的简单回答是:约2千万 为什么是这么多呢? 因为这是可以算出来的,要搞清楚这个问题,我们先从InnoDB索引数据结构.数据组织方式说起. ...

  5. 面试官:为什么MySQL的索引要使用B+树,而不是其它树?比如B树?

    InnoDB的一棵B+树可以存放多少行数据? 答案:约2千万 为什么是这么多? 因为这是可以算出来的,要搞清楚这个问题,先从InnoDB索引数据结构.数据组织方式说起. 计算机在存储数据的时候,有最小 ...

  6. MySQL存储索引InnoDB数据结构为什么使用B+树,而不是其他树呢?

    InnoDB的一棵B+树可以存放多少行数据? 答案:约2千万 为什么是这么多? 因为这是可以算出来的,要搞清楚这个问题,先从InnoDB索引数据结构.数据组织方式说起. 计算机在存储数据的时候,有最小 ...

  7. 为什么MySQL要用B+树?聊聊B+树与硬盘的前世今生【宇哥带你玩转MySQL 索引篇(二)】

    为什么MySQL要用B+树?聊聊B+树与硬盘的前世今生 在上一节,我们聊到数据库为了让我们的查询加速,通过索引方式对数据进行冗余并排序,这样我们在使用时就可以在排好序的数据里进行快速的二分查找,使得查 ...

  8. Elasticsearch 中为什么选择倒排索引而不选择 B 树索引

    目录 前言 为什么全文索引不使用 B+ 树进行存储 全文检索 正排索引 倒排索引 倒排索引如何存储数据 FOR 压缩 RBM 压缩 倒排索引如何存储 字典树(Tria Tree) FST FSM 构建 ...

  9. MySQL用B+树做索引

    索引这个词,相信大多数人已经相当熟悉了,很多人都知道MySQL的索引主要以B+树为主,但是要问到为什么用B+树,恐怕很少有人能把前因后果讲述的很完整.本文就来从头到尾介绍下数据库的索引. 索引是一种数 ...

随机推荐

  1. 计图(Jittor) 1.1版本:新增骨干网络、JIT功能升级、支持多卡训练

    计图(Jittor) 1.1版本:新增骨干网络.JIT功能升级.支持多卡训练 深度学习框架-计图(Jittor),Jittor的新版本V1.1上线了.主要变化包括: 增加了大量骨干网络的支持,增强了辅 ...

  2. GPU与显卡

    GPU与显卡 一.什么是GPU? GPU这个概念是由Nvidia公司于1999年提出的.GPU是显卡上的一块芯片,就像CPU是主板上的一块芯片.那么1999年之前显卡上就没有GPU吗?当然有,只不过那 ...

  3. CUDA 8的混合精度编程

    CUDA 8的混合精度编程 Volta和Turing GPU包含 Tensor Cores,可加速某些类型的FP16矩阵数学运算.这样可以在流行的AI框架内更快,更轻松地进行混合精度计算.要使用Ten ...

  4. 深度学习框架:GPU

    深度学习框架:GPU Deep Learning Frameworks 深度学习框架通过高级编程接口为设计.训练和验证深度神经网络提供了构建块.广泛使用的深度学习框架如MXNet.PyTorch.Te ...

  5. sql优化_隐式-显示转换

    ========  测试表1信息   =======SQL> select count(*) from tb_test; COUNT(*)----------   3000000   SQL&g ...

  6. ApplicationListener接口,在spring容器初始化后执行的方法

    一.如果我们希望在Spring容器将所有的Bean都初始化完成之后,做一些操作,那么就可以使用ApplicationListener接口,实现ApplicationListener接口中的onAppl ...

  7. 『假如我是面试官』RabbitMQ我会这样问

    1. 为什么你们公司选择RabbitMQ作为消息中间件 在消息队列选型时,我们调研了市场上比较常用ActiveMQ,RabbitMQ,RocketMQ,Kafka. RabbitMQ相对成熟稳定,这是 ...

  8. 温故知新,.Net Core遇见Blazor(FluentUI),属于未来的SPA框架

    什么是Blazor Blazor是一个使用.NET生成交互式客户端WebUI的框架: 使用C#代替JavaScript来创建信息丰富的交互式UI. 共享使用.NET编写的服务器端和客户端应用逻辑. 将 ...

  9. 4、saltstack的使用

    官方文档地址:http://repo.saltstack.com/#rhel 4.1.saltstatck介绍: 用户要一致,这里使用的是root用户: 用于批量管理成百上千的服务器: 并行的分发,使 ...

  10. 42、sort命令

    排序和把相同的放到一起: 42.1.sort命令介绍: sort命令是一个排序介绍,简而言之就是以什么为分割符,对第几列进行什么排序操作: 42.2.sort命令参数介绍: -u #去重,会直接把重复 ...