MySQL为什么采用B+树作为索引底层数据结构?

news2024/11/27 23:52:32

        索引就像一本书的目录,通过索引可以快速找到我们想要找的内容。那么什么样的数据结构可以用来实现索引呢?我们可能会想到:二叉查找树,平衡搜索树,或者是B树等等一系列的数据结构,那么为什么MySQL最终选择了B+树作为索引的数据结构呢?

索引的“要求”

        要想知道什么样的数据结构最适合索引,首先我们要知道索引需要什么?

        首先,数据库的索引时保存在磁盘上的,因此我们在查询索引的时候,要先去磁盘上读取索引到内存,然后再通过索引找到要访问的数据,最后再去磁盘中读取数据,整个过程中会发生多次IO,那么我们自然希望发生磁盘IO的次数越小越好,这样可以提高数据查询的效率。

        其次,MySQL是支持范围查找的,所以我们希望通过索引可以进行高效的范围查找

二叉查找树

二叉查找树可以在logN的时间内找到目标值,那么二叉查找树适合用作索引吗?

答案是不适合

        首先,二叉查找树存在极端情况,如果每次插入的结点都是最小或者最大的,那么二叉查找树就会退化成链表,查询的时间复杂度就从O(logN)降到了O(N)

        其次,如果索引的数量很多,树的高度也会变得很高,磁盘需要的IO次数也会不断增加。

平衡二叉树

         平衡二叉树相比于二叉查找树加上了一个条件:左右子树高度差不能超过1;虽然这个条件避免了原先二叉查找树中极端情况下会退化成链表的问题。

        但是同样的,当树中的结点不断增加的时候,树的高度高度也会不断增加,同样会使得IO次数不断增加。

B树

        实际上,二叉查找树和平衡二叉树不适合作为索引的数据结构,究其本质还是因为他们是二叉树,于是我们可以看一下m叉树的一些数据结构,比如B树。

        B树不再限制一个节点就只能有2个子节点,而是允许M个子节点 (M>2),从而降低树的高度。B树的每一个节点最多可以包括M个子节点,M称为B树的阶,所以B树就是一个多叉树

        使用了多叉树的数据结构以后,就解决了传统二叉查找树中随着索引数量的增多,IO次数会变高的问题。在实际使用中,只要M大于100,即便是千万级的数据量,仍然可以保证在3-4次IO内就找到数据。相比与传统的二叉树,多叉树会更加矮胖,更适合作为索引的数据结构。

但是,MySQL仍然没有选择B树,为什么呢?

        首先B树的每个节点都包含数据(索引+记录),而用户的记录数据的大小很有可能远远超过了索引数据,这就需要花费更多的磁盘 I/O 操作次数来读到真正需要的索引数据信息。

        其次,MySQL是支持范围查询的,B树进行范围查询需要进行树的中序遍历,需要使用递归或者迭代搜索来进行遍历,效率不高。

B+树

最后,MySQL选择了B+树,B+树的结构大致如下所示:

B+树和B树很相似,差异如下:

  • 叶子节点(最底部的节点)才会存放实际数据(索引+记录),非叶子节点只会存放索引

  • 所有索引都会在叶子节点出现,叶子节点之间构成一个有序链表;

 这样就解决了B树的两个缺陷。

        B+树的非叶子节点不存放实际的记录数据,仅存放索引,因此数据量相同的情况下,相比存储即存索引又存记录的B树,B+树的非叶子节点可以存放更多的索引,因此B+树可以比B树更矮胖,查询底层节点的磁盘 I/O次数会更少。

        B+树所有叶子结点使用双向链表连接,这使得其进行范围查找的时候,十分方便,相较于B树范围查询效率更高。

总结

为什么采用B+树作为索引的数据结构?

1.和传统的二叉查找树相比,B+树是一棵多叉树,树的高度更小,整个树更加矮胖,查询的效率更高;二叉树的话,数据量上去了树的高度就会很高。

(tips:实际使用中,m的值会超过100,此时即便是千万级的数据量,仍然可以保证在3-4次IO内就找到数据)

2.和B树相比

  • B+树的磁盘IO效率更高。B+树的数据只会存放在叶子结点(非叶子节点只存索引信息),而B树在每个节点上都要存放数据,所以在相同的空间内,B+树可以存放更多地索引信息,IO效率更高(单次IO获得的索引信息量更大)
  • B+树范围查找效率更高,B树进行范围查找需要进行树中序遍历,而B+树的叶子结点使用了双向链表连接起来,范围查找效率更高。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/742132.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

尚硅谷Docker实战教程-笔记12【高级篇,Docker-compose容器编排】

尚硅谷大数据技术-教程-学习路线-笔记汇总表【课程资料下载】视频地址:尚硅谷Docker实战教程(docker教程天花板)_哔哩哔哩_bilibili 尚硅谷Docker实战教程-笔记01【基础篇,Docker理念简介、官网介绍、平台入门图解、平台架构图解】…

一篇文章搞懂Libevent网络库的原理与应用

1. Libevent介绍 Libevent 是一个用C语言编写的、轻量级的开源高性能事件通知库,主要有以下几个亮点: > - 事件驱动( event-driven),高性能; > - 轻量级,专注于网络; > - 源代码相当…

前端(五)——从 Vue.js 到 UniApp:开启一次全新的跨平台开发之旅

🙂博主:小猫娃来啦 🙂文章核心:从 Vue.js 到 UniApp:开启一次全新的跨平台开发之旅 文章目录 UniApp和vue.js什么是UniApp?UniApp的写法什么是vue.js?UniApp与vue.js是什么关系? 为什…

Python+Appium+Pytest自动化测试-参数化设置

来自APP Android端自动化测试初学者的笔记,写的不对的地方大家多多指教哦。(所有内容均以微博V10.11.2版本作为例子) 在自动化测试用例执行过程中,经常出现执行相同的用例,但传入不同的参数,导致我们需要重…

【Redis基础】快速入门

一、初识Redis 1. 认识NoSQL 2. 认识Redis Redis诞生于2009年,全称是Remote Dictionary Server(远程词典服务器),是一个基于内存的键值型NoSQL数据库特征 (1)键值(key-value)型&am…

测试员如何突破自我的瓶颈?我有几点看法

前阵子我自己也对如何“突破瓶颈”思考过,我觉得“突破瓶颈”、“弥补短板”等等都大同小异,从古至今就是测试员们津津乐道的话题。我也对自己该如何“突破瓶颈”总结了几点,跟大家分享下: 1、“常立志、立长志”。“立志”就是目…

Vue脚手架使用【快速入门】

一、使用vue脚手架创建工程 在黑窗口中输入vue ui命令 再更改完路径地址后需要按回车 二、vue工程中安装elementui 第一种可以在黑窗口输入命令安装 npm install -s element-ui第二种使用图形化安装 三、 在vue工程中安装axios 第一种可以在黑窗口输入命令安装 npm inst…

ECMAScript6之一

目录 一、介绍 二、新特性 2.1 let 和 const 命令 2.2 es6的模板字符串 2.3 增强的函数 2.4 扩展的字符串、对象、数组功能 2.5 解构赋值 2.6 Symbol 2.7 Map 和 Set 2.8 迭代器和生成器 2.9 Promise对象 2.10 Proxy对象 2.11 async的用法 2.22 类class 2.23 模块…

linux内核中kmalloc与vmalloc

kmalloc 和 vmalloc 是 Linux 内核中的两种内存分配方法,它们都用于为内核分配内存,但它们在使用和管理内存方面存在一些重要差异。下面我们详细讨论这两种内存分配方法的异同。 相同点: 都是内核空间的内存分配方法。都可以用于动态分配内…

anaconda目录下的pkgs文件夹很大,可以删除吗?

pkgs这个目录占用了6GB的硬盘空间。 其实里面是conda安装第三方包的时候保存在本地的下载文件,大部分是可以删除的。 只是删除后,后续你需要创建虚拟环境的时候或者在虚拟环境下pip安装第三方库的时候,会从网络去下载,没法直接从…

Jmeter的常用设置(一)

文章目录 前言一、Jmeter设置中文 方法一(临时改为中文)方法二(永久改成中文)二、启动Jmeter的两种方式 方法一(直接启动,不打开cmd窗口)方法二(带有cmd窗口的启动)三、调…

【xxl-job】本地部署并接入xxl-job到项目中

本地部署并接入xxl-job到项目中 一、xxl-job简介 XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。 什么是分布式任务调度 通常任务调度的程序是集成在应用…

SparkCoreDAG

DAG有向无环图 倒推 故推导程序的执行计划时,先看代码有几个action算子,从action倒推 一个action会产生一个JOB(DAG)(即一个应用程序内的子任务) 一个action一个Job一个DAG 一个application里面可以有多…

Latex:画图识别符号

http://detexify.kirelabs.org/classify.html

RDMA RoCev2 CM建链和Socket建链测试

前言 RDMA在高性能计算,AI大模型训练中发挥着重要的作用。 主流支持RDMA的协议有IB、RoCev1、RoCev2、iWARP。 其中RoCev2是应用最广泛的协议,因为其RDMA over UDP/IP,不依赖昂贵的IB网络设备,同时支持路由,性能上也…

Azure Kinect 之 Note(一)

Azure Kinect Azure Kinect DK 是一款开发人员工具包,配有先进的AI 传感器,提供复杂的计算机视觉和语音模型。 Kinect 将深度传感器、空间麦克风阵列与视频摄像头和方向传感器整合成一体式的小型设备,提供多种模式、选项和软件开发工具包(S…

Web开发模式

Web开发介绍 1 什么是web开发 Web:全球广域网,也称为万维网(www World Wide Web),能够通过浏览器访问的网站。 所以Web开发说白了,就是开发网站的,例如下图所示的网站:淘宝,京东等等 那么我们…

【*2400 线段树】CF444 C

Problem - C - Codeforces 题意: 思路: 首先询问的是权值和,那么维护一个区间和sum,因此pushup部分就好了 考虑修改,区间修改,因此要打标记 一次修改对区间和的贡献不能直接计算,因此我们考…

8-1、Deployment运行应用的机制

Kubernetes 通过各种 Controller 来管理 Pod 的生命周期。为了满足不同业务场景,Kubernetes 开发了 Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job 、 CronJob 等多种 Controller。 用户通过 kubectl 创建 Depl…

ENSP模拟器如何设置命令行和描述框的背景颜色及字体

ENSP模拟器如何设置命令行和描述框的背景颜色及字体 选择“菜单 > 工具 > 选项”, 在弹出界面中选择“字体设置”。 单击“字体”后的“选择”设置字体,单击“字体颜色”后的“选择”设置字颜色,单击“背景颜色”后的“选择”设置…