B+树简介

在正式介绍本文的主题前,需要对 B+ 树有一定的了解,B+树是一种磁盘上数据的索引结构,大概长这个样子。

B+树的叶子节点是所有的数据,非叶子节点称为索引页,索引页里有若干个索引项,本例中有 3 个索引项,也就是索引页的出度为 3,表示它有 3 个子节点。

相要寻找某一个数据时,比如值为 6 的数据,只需要先在索引页中找到小于 6 的最大的索引项 4,就可以索引到保存了 4,5,6 三条数据的数据页,进而找到值为 6 的这一条数据。

当然,B+ 树不是只有一个索引节点,只是为了方便展示所以图中只有一个索引节点,一个更大的 B+ 树如下图所示。

数学推导

假设 B+ 树总共索引了 N 条数据(叶子节点的数据量),每个索引页的出度为 EntriesPerPage(索引页内有多少个索引项),则 B+ 树的高度可以由如下式子计算:

\[IndexHeight \approx \frac{log_{2}{N}}{log_{2}{EntriesPerPage}}
\]

定义 IndexPageUtility 为衡量索引页到数据页的远近的指标,可以由如下式子计算:

\[IndexPageUtility = log_{2}{EntriesPerPage}
\]

这里可以不必纠结为什么 utility 就是这么算的,只要理解 utility 和 EntriesPerPage 是正相关的关系就可以,因为最后算的收益成本比率只是一个比值,能比较出大小就可以,所以这里就取 utility 为 IndexHeight 计算公式的分母。

举个例子,如果索引项大小为 20 字节,那么 2KB 的索引页应该是能装下 100 个索引项,但实际上索引页内不仅仅只存有索引项,实际索引项最高能占用 70% 的空间,也就是 70 个索引项。这样的索引页的 utility 为 \(log_{2}{70}\) 约为 6.2,大约是 128KB 大小索引页 utility 的一半。

每一次读索引页都需要读一次磁盘,相应的距离目标数据也更进一步(使用 utility 衡量步长)。基于这种成本效益的权衡,产生了一个最佳的页面大小,平衡了读一次索引页的收益(IndexPageUtility)和成本(IndexPageAccessCost)。

对于越大的索引页,它的出度越大,utility 越高,从磁盘读取的成本也越高,对于特定的磁盘的寻址时间和传输速率,有一个最优的索引页大小。

假设磁盘平均寻址时间为 10 毫秒,传输速率为 10MB 每秒,索引页大小为 2KB,那么读取索引页需要的时间为 10.2 毫秒。

更准确的说,读取索引页的成本要么是有页面缓存时的内存存储成本,要么是从磁盘读取页面的磁盘访问成本。如果根索引页及附近的索引页缓存在内存中,能够节省一个数量恒定的 IO 次数,这个数量一般是可以忽略的。

因此从磁盘读取索引页的成本可以由如下式子计算,DiskLatency 为磁盘寻址时间。

\[IndexPageAccessCost = DiskLatency + \frac{PageSize}{DiskTransferRate}
\]

那么读取索引页的收益和成本的比率就是:

\[BenefitCostRatio = \frac{IndexPageUtility}{IndexPageAccessCost}
\]

应用分析

假设磁盘平均寻址时间为 10 毫秒,传输速率为 10MB 每秒,索引项大小为 20 字节,下表给出不同索引页大小对应的收益成本比率。

IndexPageSize(KB) EntriesPerPage IndexPageUtility IndexPageAccessCost BenefitCostRatio
2 68 6.1 10.2 0.60
4 135 7.1 10.4 0.68
8 270 8.1 10.8 0.75
16 541 9.1 11.6 0.78
32 1081 10.1 13.2 0.76
64 2163 11.1 16.4 0.68
128 4325 12.1 22.8 0.53

通过上表可以得出,索引页大小在 8KB 到 32KB 是收益成本比率是最优的。索引页过小或过大都不是好的选择。且该索引页大小范围也随着磁盘传输速率的提升而发生变化,当传输速率为 40MB 每秒,最优的索引页大小将变成 32KB 到 128 KB。

B+树索引页大小是如何确定的?的更多相关文章

  1. MySQL:InnoDB存储引擎的B+树索引算法

    很早之前,就从学校的图书馆借了MySQL技术内幕,InnoDB存储引擎这本书,但一直草草阅读,做的笔记也有些凌乱,趁着现在大四了,课程稍微少了一点,整理一下笔记,按照专题写一些,加深一下印象,不枉读了 ...

  2. MySQL的B树索引与索引优化

    MySQL的MyISAM.InnoDB引擎默认均使用B+树索引(查询时都显示为"BTREE"),本文讨论两个问题: 为什么MySQL等主流数据库选择B+树的索引结构? 如何基于索引 ...

  3. 搞懂MySQL InnoDB B+树索引

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

  4. MySQL之B+树索引(转自掘金小册 MySQL是怎样运行的,版权归作者所有!)

    每个索引都对应一棵B+树,B+树分为好多层,最下边一层是叶子节点,其余的是内节点.所有用户记录都存储在B+树的叶子节点,所有目录项记录都存储在内节点. InnoDB存储引擎会自动为主键(如果没有它会自 ...

  5. [MySQL] 索引中的b树索引

    1.索引如果没有特别指明类型,一般是说b树索引,b树索引使用b树数据结构存储数据,实际上很多存储引擎使用的是b+树,每一个叶子节点都包含指向下一个叶子节点的指针,从而方便叶子节点的范围遍历 2.底层的 ...

  6. InnoDB存储引擎的 B+ 树索引

    B+ 树是为磁盘设计的 m 叉平衡查找树,在B+树中,所有的记录都是按照键值的大小,顺序存放在同一层的叶子节点上,各叶子节点组成双链表.叶节点是数据,非叶节点是索引. 首先,需要清楚:B+ 树索引并不 ...

  7. InnoDB存储引擎的B+树索引算法

    关于B+树数据结构 ①InnoDB存储引擎支持两种常见的索引. 一种是B+树,一种是哈希. B+树中的B代表的意思不是二叉(binary),而是平衡(balance),因为B+树最早是从平衡二叉树演化 ...

  8. MySQL中B+树索引的使用

    1)         不同应用中B+树索引的使用 对于OLTP应用,由于数据量获取可能是其中一小部分,建立B+树索引是有异议时的 对OLAP应用,情况比较复杂,因为索引的添加应该是宏观的而不是微观的. ...

  9. B树索引与索引优化

    B树索引与索引优化 MySQL的MyISAM.InnoDB引擎默认均使用B+树索引(查询时都显示为“BTREE”),本文讨论两个问题: 为什么MySQL等主流数据库选择B+树的索引结构? 如何基于索引 ...

随机推荐

  1. 6.Docker网络

    什么是 Docker网络 docker 不启动,默认网络情况 ens33 lo virbr0 在 CentOS7 的安装过程中如果有选择相关虚拟化的的服务安装系统后,启动网卡时会发现有一个以网桥连接的 ...

  2. 使用Spring MVC开发RESTful API(续)

    使用多线程提高REST服务性能 异步处理REST服务,提高服务器吞吐量 使用Runnable异步处理Rest服务 AsyncController.java @RestController @GetMa ...

  3. 基于.NetCore开发博客项目 StarBlog - (9) 图片批量导入

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...

  4. Java概论——JavaSE基础

    Java概论 Java特性和优势 简单性 面向对象 可移植性 高性能:即时编译 分布式:可处理TCP/IP协议的一些东西 动态性:通过反射机制使其具有动态性 多线程:良好的交互性和实时性 安全性:防病 ...

  5. VSCode 安装以及初步使用教程

    老样子先介绍一下VSCode(是什么?干什么?有什么用?好处是什么?等) VisualStudioCode(简称VSCode)是Microsoft开发的代码编辑器,它支持Windows,Linux和m ...

  6. 微前端(qiankun)主应用共享React组件

    前言 最近需要重构一个老项目,定的方案用微前端去改造.主应用是老的项目,微应用是新的项目,由于重构时间比较紧张,子应用还需要使用父应用的一些组件.过程中遇到一些问题,记录一下. 方案 我们知道qian ...

  7. C语言 - 基础数据结构和算法 - 单向链表

    听黑马程序员教程<基础数据结构和算法 (C版本)>,照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友可 ...

  8. 纯css就能实现可点击切换的轮播图,feel起来很丝滑

    前言 轮播图经常会在项目里用到,但是实际上用到的轮播图都是比较简单的,没有复杂的特效,这个时候如果去引入swiper那些库的话,未免就有点杀鸡焉用牛刀了. 所以不如自己手写一个,而今天我要分享的一种写 ...

  9. 关于升级最新版本node.js你知道多少?

    1.先检查版本 node -v 2.清除缓存 npm cache clean -f 3.全局安装管理node.js版本工具 npm install -g n 4.确认安装最新版本 n stable 5 ...

  10. node环境下怎样优化引入多文件(实现自动化)

    const mocks = [];function getJsonFiles(jsonPath) {function findJsonFile(path) {let files = fs.readdi ...