hello,大家好,我是张张,「架构精进之路」公号作者。

提到MySQL,想必大多后端同学都不会陌生,提到B+树,想必还是有很大部分都知道InnoDB引擎的索引实现,利用了B+树的数据结构。

那InnoDB 的一棵B+树可以存放多少行数据?它又有多高呢?

到底是哪些因素会对此造成影响呢,今天我们就来展开聊一下。

1InnoDB引擎数据存储

在计算机中,磁盘存储数据最小单元是扇区,一个扇区的大小是512字节,而文件系统(例如XFS/EXT4)的最小单元是块,一个块的大小是4k,在InnoDB存储引擎中,也有页(Page)的概念,默认每个页的大小为16K,也就是每次读取数据时都是读取4*4k的大小!

在MySQL中,InnoDB页的大小默认是16k,当然也可以通过参数设置:

2InnoDB引擎数据操作

接下来,为了让大家能更好地理解数据存储逻辑,我们来进行一个数据操作实例进行讲解。

假设我们现在有一个用户表,我们往里面写入数据。

这里需要注意的一点是,在某个页内插入新数据行时,为了减少数据的移动,通常是插入到当前行的后面或者是已删除行留下来的空间,所以在某一个页内的数据并不是完全有序的。但是为了为了数据访问顺序性,在每个记录中都有一个指向下一条记录的指针,因此构成了一条单向有序链表。

当数据还比较少时,一个页就能容下,所以只有一个根结点,主键和数据也都是保存在根结点(左边的数字代表主键,右边姓名、性别代表具体的记录数据)。

假设我们写入10条数据之后,Page1满了,再写入新的数据会怎么存放呢?

有个叫“无名氏”的朋友来了,但是Page1已经放不下数据了,这时候就需要进行页分裂,产生一个新的Page页。

在InnoDB 中的页分裂流程是怎么样的呢?

1、产生新的Page2,然后将Page1的内容复制到Page2。

2、产生新的Page3,“无名氏”的数据放入Page3。

3、原来的Page1依然作为根结点,但是变成了一个不存放数据只存放索引的页,并且有两个子结点Page2、Page3。

看到这里,大家可能会有两个问题:

Q1:为什么要复制Page1为Page2呢?直接创建一个新的页作为根结点,这样不就少了一次复制的开销么?

A:如果是新创建根结点,那根结点存储的物理地址可能经常会变,不利于查找。并且在InnoDB中根结点是会预读到内存中的,所以结点的物理地址固定会比较好。

Q2:原来Page1有10条数据,在插入第11条数据的时候进行页裂变,根据对B-Tree、B+Tree特性的了解,那这至少是一颗11阶的树,裂变之后每个结点的元素至少为11/2=5个,那是不是应该页裂变之后主键1-5的数据还是在原来的页,主键6-11的数据会放到新的页,根结点存放主键6呢?

A:如果是这样的话,新的页空间利用率只有50%,并且会导致更为频繁的页分裂。所以InnoDB对这一点做了优化,新的数据放入新创建的页,不移动原有页面的任何记录。

随着数据的不断写入,这棵树也逐渐枝繁叶茂,如下图:

  每次新增数据,都是将一个页写满,然后新创建一个页继续写,这里其实是有个隐含条件的,那就是主键自增!主键自增写入时新插入的数据不会影响到原有页,插入效率高!且页的利用率高!但是如果主键是无序的或者随机的,那每次的插入可能会导致原有页频繁的分裂,影响插入效率!降低页的利用率!这也是为什么在InnoDB中建议设置主键自增的原因!

  这棵树的非叶子结点上存的都是主键,那如果一个表没有主键会怎么样?在InnoDB中,如果一个表没有主键,那默认会找建了唯一索引的列,如果也没有,则会生成一个隐形的字段作为主键!

  有数据插入那就有删除,如果这个用户表频繁的插入和删除,那会导致数据页产生碎片,页的空间利用率低,还会导致树变的“虚高”,降低查询效率!这可以通过索引重建来消除碎片提高查询效率!

3InnoDB引擎索引高度

回到开篇的问题:InnoDB 的一棵B+树可以存放多少行数据?它又有多高呢?

这个需要区分叶子节点和非叶子节点:

  • 非叶子节点

InnoDB 存储引擎默认一个数据页大小为16kb,非叶子节点存放(key,pointer),假设主键ID为bigint类型,长度为8字节,而指针大小在InnoDB源码中设置为6字节,这样一共14字节,即非叶子节点能存放 16kb/14 左右的key,pointer。

  • 叶子节点

单个叶子节点(页)中的记录数 = 16K/1K = 16。

这里我们假设一行记录的数据大小为1k左右

总结一下:

如果B+树高度为2的话,那么这棵B+树的存放总记录数为:根节点指针数*单个叶子节点记录行数 = 16kb/14 * 16 大约 1.8w+ 数据。

如果B+树高度为3的话,那么这棵B+树的存放总记录数为:根节点指针数*单个叶子节点记录行数 = 16kb/14 * 16kb/14 * 16 大约2kw+数据。

因此常见 InnoDB存储引擎B+树的高度基本为2-3


希望今天的讲解对大家有所帮助,谢谢!

Thanks for reading!

关注公众号,免费领学习资料

如果您觉得还不错,欢迎关注和转发~

是什么影响了MySQL索引B+树的高度?相关推荐

  1. MySQL索引-B+树(看完你就明白了)

    索引是一种数据结构,用于帮助我们在大量数据中快速定位到我们想要查找的数据. 索引最形象的比喻就是图书的目录了.注意这里的大量,数据量大了索引才显得有意义,如果我想要在 [1,2,3,4] 中找到 4 ...

  2. mysql 查询相同字段值的个数_好文 | MySQL 索引B+树原理,以及建索引的几大原则...

    MySQL事实上使用不同的存储引擎也是有很大区别的,下面猿友们可以了解一下. 一.存储引擎的比较 注:上面提到的B树索引并没有指出是B-Tree和B+Tree索引,但是B-树和B+树的定义是有区别的. ...

  3. mysql索引 b树_B树与MySQL数据库索引.ppt

    B树与MySQL数据库索引 * B+树及MySQL数据库索引 厦门大学数据库实验室 罗道文 2014-08-02 ?B树以及B+树的特点以及原理 ?MySQL存储引擎MyISAM和InnoDB的B+树 ...

  4. mysql索引结构树高度_MYSQL的B+Tree索引树高度如何计算

    前一段被问到一个平时没有关注到有关于MYSQL索引相关的问题点,被问到一个表有3000万记录,假如有一列占8位字节的字段,根据这一列建索引的话索引树的高度是多少? 这一问当时就被问蒙了,平时这也只关注 ...

  5. mysql索引b树和hash_B树索引和Hash索引的应用场景和区别(转载)

    转自:https://blog.csdn.net/chuangsun/article/details/78013537 关系型数据库中,索引大多采用B/B+树来作为存储结构,而全文搜索引擎的索引则主要 ...

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

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

  7. mysql联合索引B 树_B+树和Mysql索引详解

    B+树总结 根据以下几篇文章总结的自己的心得,便于自己理解 B+树内部平衡详解 B+树存储原理 B+树存储 MySQL索引-B+树(看完你就明白了) 从B树.B+树.B*树谈到R 树 我们一般看到的B ...

  8. mysql 什么树_搞懂MySQL InnoDB B+树索引

    一.InnoDB索引 InnoDB支持以下几种索引: B+树索引 全文索引 哈希索引 本文将着重介绍B+树索引.其他两个全文索引和哈希索引只是做简单介绍一笔带过. 哈希索引是自适应的,也就是说这个不能 ...

  9. MySQL索引背后的数据结构及算法原理--转

    MySQL索引背后的数据结构及算法原理 作者 张洋 | 发布于 2011-10-18 MySQL 索引 B树 优化 原文地址:http://blog.codinglabs.org/articles/t ...

最新文章

  1. 【python语言基础】疑难点整理1
  2. 访问备份数据寄存器时,需要打开BKP时钟吗?
  3. WEB前端技术趋势图示-JS库
  4. 【公告】社区周刊即日起停刊
  5. 解放人与设备距离,5G时代的远程操控该如何完成
  6. 13万张表+数亿行代码,迁移只需数小时,还是异构数据库
  7. pytorch构造IterableDataset,流式读取文件夹,文件夹下所有大数据文件,逐个文件!逐行读取!(pytorch Data学习四)
  8. 实验四 lr0分析程序的设计与实现_试验机海外直播丨实现高精度CAE分析实验的材料评价案例技术介绍...
  9. Vert.x 异步访问数据库 MySQL
  10. 编程求完全二叉树的叶子结点数
  11. love~LBJ,奥布莱恩神杯3
  12. vscode配置esp32开发环境:ESP-IDF VS Code Extension 没有 Using Existing Setup
  13. python获取上周周一日期_python python日期算法 本周,上周,本月,上月,本季,上季,今年, 去年...
  14. 【只推荐一位】木东居士,数据挖掘的大神!
  15. cesium接入百度影像地图(cesium篇.27)
  16. ubuntu启动两个mysql_同一台Ubuntu 启动多个mysql
  17. MCS-51单片机C语言程序注释,精通MCS-51单片机C语言编程
  18. 国产飞腾服务器制作raid
  19. 关于qmail的笔记
  20. python网页信息违法吗_爬虫到底违法吗?这位爬虫工程师给出了答案

热门文章

  1. Handlerbars基础笔记
  2. BI智慧仓储,带你体验数字化仓储物流管理
  3. Python初学习--你的历史我想知道一下
  4. 关于显卡驱动引起的IE异常停止工作解决办法
  5. [经验教程]2022淘宝天猫618定金可以退吗及2022年淘宝天猫618超级红包活动时间是什么时候开始到几月几号结束活动优惠力度大吗?
  6. 索尼koov机器人比赛_索尼KOOV机器人诞生2周年纪念日新起点一起再出发
  7. android刘海屏适配方案
  8. fir.im Weekly - 除了新 MacBook Pro,近期值得关注的移动开发好资源 1
  9. UBUNTU时间同步
  10. linux ntp时钟服务器地址_Linux配置时间同步以及国内常用的NTP服务器地址