索引选择的艺术:MySQL为何青睐B+树?

server/2024/10/23 6:14:23/

索引选择的艺术:MySQL为何青睐B+树?

案例数据:表a有如下两个字段,且两个字段数据如下

字段a(主键)1234567
字段b1293118366969

接下来将以常见的几种数据结构来看看进行比对,为什么MySQL最终使用了B+Tree(B+树)作为索引的数据结构。

索引的数据结构可以有如下几种:二叉树、平衡二叉树、红黑树、Hash表、B-Tree、B+Tree;

1. 二叉树(二叉查找树)

如果索引数据结构是二叉树(二叉查找树)(有序的):

字段b 的索引结构为

请添加图片描述

此时如果要查询数据 83 ,则查询路径为12–93–83,查询的很快,看起来很适合做索引的数据结构。

但是如果给 字段a 按照二叉树(二叉查找树)结构排好序,则为

请添加图片描述

此时如果要查询数据 7 ,则查询路径为1–2–3–4–5–6–7,将所有数据都遍历了一遍,相当于是一个链表了,查询效率就很低。

所以二叉树(二叉查找树)不适合查询有序数据,所以没有被应用于mysql的索引结构。

2. 平衡二叉树

请添加图片描述

平衡二叉树可以很好的解决二叉查找树遇到有序数据导致成为链表的情况。应为平衡二叉树有自平衡的特性,左右子树其中一边太长了之后,会触发平衡调整操作,进行旋转,保持树的左右子树平衡。

具体的概念和平衡二叉树的平衡调整操作过程可以看 《 平衡二叉树 》 。

那为什么mysql不使用平衡二叉树做索引结构呢?因为平衡二叉树太注重平衡性,需要经常进行平衡调整,操作过于频繁,会影响性能。

3. 红黑树

请添加图片描述

红黑树是一个弱平衡的二叉树,虽然也需要进行旋转操作,但是他不需要去保持整棵树的平衡,每次插入操作最多也只会旋转2次,极大程度减少了平衡调整操作的次数,从而操作性能红黑树比平衡二叉树要高。

而且红黑树和平衡二叉树的查询性能都为O(logn)。

但即使如此,他依旧不适合用当做mysql的索引结构,因为当数据量大了之后,红黑树树的高度是不可控的,树的高度越高,查询比较次数就越多,性能也就越低下。

4. B-Tree(B树)

红黑树的高度不可控,于是就出现了B树,B树的每一个节点是一个页,一页有16KB大小,每页里面都放满了索引元素,假如一条数据有5KB大小,那么就是一页里面可以放3个索引元素(B树的索引节点是同时存放整行业务数据的),那么他的示意图如下

请添加图片描述

所有索引元素不重复,且从左到右是递增排列的。

B树解决了红黑树高度不可控的因素,一个节点一页存储多个索引元素,很大程度上减少了树的高度。但是又因为每个索引元素都是会同时存储整行数据的,所以一页大小16KB,也存不了多少行。所以MySQL也没有使用B树,而是使用了B树的一个变种,B+树。

5. B+Tree(B+树)

请添加图片描述

B+树是B树的变种,非叶子节点,不会再存放索引对应的整行data数据,而是只存储冗余的索引字段,和数据页的地址。

且在B+树中,上层的非叶子节点的索引数据都是 冗余索引 ,就是最终获取数据是必须要一直查询到叶子节点,才可以获取到(非叶子节点不再存储整行数据)。

冗余索引:是从叶子节点里提取出来的索引,就叫冗余索引,提取出来的冗余索引和叶子节点一起组成构建了一个B+树。冗余索引都是每个叶子节点的第一个(一页数据的第一条索引)。

上图中的0003就是[0003, 0004]叶子节点(也可以理解为一页)里提取的第一个索引数据。0005就是[0005, 0006, 0007]叶子节点里提取的第一个索引数据。

而叶子节点是包含了所有的索引字段的,同时页子节点之间有指针连接,可以提高区间的访问性能。

例如:要查询0004,则先在第一层进行判断,0004>0003且0004<0005,所以就是在0003和0005之间,就拿到对应数据页的磁盘地址,然后就到[0003,0004]这一页的叶子节点里进行查找(用二分查找等算法)就能拿到0004的数据。

使用B+树作为MySQL的索引结构,只需要3层树的高度,就可以存储大概2千万~3千万的数据量。查询数据也只需要进行3次IO查询即可。

注意:只有主键索引的叶子节点才会存储整行数据,而非主键索引,其叶子节点存储的数据是主键Id,需要回表才能获取到整行数据。

关注我,我将持续输出Java常用相关技术文章。
请添加图片描述


http://www.ppmy.cn/server/134093.html

相关文章

知识图谱推理(论文复现)

本文所涉及所有资源均在 传知代码平台 可获取。 目录 1. 论文概述 2. 论文方法 3. 实验部分

Elasticsearch 在linux部署 及 Docker 集群部署详解案例示范

1. 在 CentOS 上安装和配置 Elasticsearch 在 CentOS 系统下&#xff0c;安装 Elasticsearch 主要分为以下步骤&#xff1a; 1.1 准备工作 在开始安装之前&#xff0c;确保你的系统满足以下基本条件&#xff1a; CentOS 版本要求&#xff1a;推荐使用 CentOS 7 及以上版本。…

【Vulnhub靶场】Kioptrix Level 5

目标 本地IP&#xff1a;192.168.118.128 目标IP&#xff1a;192.168.118.0/24 信息收集 nmap探测存活主机&#xff0c;扫全端口&#xff0c;扫服务 首先探测到目标ip为&#xff1a;192.168.118.136 nmap -sP 192.168.118.0/24nmap -p- 192.168.118.136nmap -sV -A 192.168.…

达梦数据库使用 Flyway

参考&#xff1a;db-migration: Flyway、Liquibase 扩展支持达梦&#xff08;DM&#xff09;数据库、南大通用&#xff08;GBase 8s&#xff09;数据库&#xff0c;并支持 Flowable 工作流。 需要注意的是&#xff0c;下面两个依赖的顺序不能颠倒&#xff0c;因为有冲突的类 …

计算机毕业设计Python+Spark知识图谱课程推荐系统 课程用户画像系统 课程大数据 课程爬虫 课程大屏 mooc慕课推荐系统 大数据毕业设计

《PythonSpark知识图谱课程推荐系统》开题报告 一、研究背景与意义 随着互联网技术的快速发展&#xff0c;在线教育平台已成为人们获取知识、提升技能的重要途径。然而&#xff0c;面对海量的课程资源&#xff0c;用户往往难以快速找到符合自己兴趣和需求的课程。传统的课程推…

代码随想录算法训练营第二十二天 | 回溯理论基础 77.组合 216.组合总和Ⅲ 17.电话号码的字母组合

回溯理论基础&#xff1a; 回溯效率: 回溯本质上是穷举&#xff0c;从所有答案中选出想要的。会增加一些剪枝的操作 回溯法解决的问题&#xff1a; 组合&#xff1a;N个数中找k个数的集合切割&#xff1a;一个字符串按一定规则有几种切割方式子集&#xff1a;一个N个数的集…

nginx的负载均衡配置和重定向

upstream_check模块 配置文件详情 upstream cluster1{server 10.0.0.4:80 weight1 max_fails3 fail_timeout30s;server 10.0.0.5:80 weight1 max_fsils3 fsil_tomeout;check interval3000 rise2 fall5 timeout1000 typehttp;check interval3000 rise2 fall5 timeout1000…

Java方法重载

Java方法重载是指在一个类中&#xff0c;可以声明多个方法具有相同的名称&#xff0c;但是参数列表不同&#xff08;参数类型、参数个数或者参数顺序不同&#xff09;的情况。在调用方法时&#xff0c;编译器根据参数的类型、顺序和个数来确定调用的是哪个方法。 方法重载的目…