MySQL索引

【MySQL】MySQL索引为何使用B+树结构,而不是二叉树、红黑树、B树? 本章节我们主要来聊聊 MySQL索引为何使用B+树结构,而不是二叉树、红黑树、B树?MysQL的索引机制中,有一点可谓是路人皆知,既默认使用B+树作为底层的数据结构。有人会说树结构是以二分法查找数据,所以会在很大程度上提升检索性能,这点确实没错,但树结构有那么多,但为什么要选择B+树呢?而不选择二叉树、红黑树或B树呢?下面一起聊一聊这个话题。 阅读详情

索引

说说数据库索引的底层数据结构

数据库(不单指MySQL)索引可选的底层数据机构包括:

  • 二叉树

  • 红黑树

  • Hash表

  • B-Tree

但mysql索引的底层用的并不是二叉树和红黑树。因为二叉树和红黑树在某些场景下都会暴露出一些缺陷。

首先,二叉树在某些场景下会退化成链表,而链表的查找需要从头部开始遍历,而这就失去了加索引的意义。

不使用红黑树的原因是:红黑树作为底层数据结构在面对在些表数据动辄数百万数千万的场景时,会导致索引树的层数很高。索引从根节点开始查找,而如果我们需要查找的数据在底层的叶子节点上,那么树的高度是多少,就要进行多少次查找,数据存在磁盘上,访问需要进行磁盘IO,这会导致效率过低;

而B+树由B树和索引顺序访问方法演化而来,它是为磁盘或其他直接存取辅助设备设计的一种平衡查找树,在B+树中,所有记录节点都是按键值的大小顺序存放在同一层的叶子节点,各叶子节点通过指针进行链接。

B+树索引在数据库中的一个特点就是高扇出性,例如在InnoDB存储引擎中,每个页的大小为16KB。在数据库中,B+树的高度一般都在2~4层,这意味着查找某一键值最多只需要2到4次IO操作,这还不错。因为现在一般的磁盘每秒至少可以做100次IO操作,2~4次的IO操作意味着查询时间只需0.02~0.04秒。

为什么B+树的高度一般不会超过4层:

真实一个数据页可以存100条记录, 一个目录页能存1000条数据;4层B+树能存一千万条数据,我们用到的B+树都不会超过4层,每个页内部可以用二分查找更快查找。

InnoDB非聚簇索引情况:

InnoDB 页的大小为 16KB,一般表的主键类型为 INT(占用4个字节)或 BIGINT (占用8个字节),指针类型也一般为4或8个字节,也就是说一个页 (B+Tree 中的一个节点)中大概存储16KB/(8B+8B)=1K个键值 (因为是估值,为方便计算,这里的K取值为 10^3。也就是说一个深度为3的B+Tree 索引可以维护 10^310^310^3= 1 亿条记录(这里假定一个数据页也存储10A3条行记录数据了)

实际情况中每个节点可能不能填充满,因此在数据库中,B+Tree 的高度一般都在 2~4 层。MySQL的lnnoDB 存储引擎在设计时是将根节点常驻内存的,也就是说查找某一键值的行记录时最多只需要 2~4 次磁盘IO操作。

数据页大小:

MyISAM 的数据页大小是固定的,是 1KB,也就是说,MyISAM 存储引擎的数据都是以 1KB 的块进行管理的。

InnoDB 存储引擎的数据页大小是可调的,默认是 16KB。在 MySQL 5.7 版本之前,InnoDB 的数据页大小默认是 8KB。可以通过参数 innodb_page_size 来设置 InnoDB 的数据页大小,取值范围是 4KB、8KB、16KB 和 32KB。

请你说说索引怎么实现的B+树,为什么选这个数据结构?

索引本质上就是通过预排序+树型结构来加快检索的效率,而MySQL中使用InnoDB和MyISAM引擎时都使用了B+树实现索引。

它是一棵平衡多路查找树,是在二叉查找树基础上的改进数据结构。在二叉查找树上查找一个数据时,最坏情况的查找次数为树的深度,当数据量很大时,查询次数可能还是很大,造成大量的磁盘IO,从而影响查询效率;

为了减少磁盘IO的次数,必须降低树的深度,因此在二叉查找树基础上将树改成了多叉加上一些限制条件,就形成了B树;

B+树中所有叶子节点值的总集就是全部关键字集合;B+树为所有叶子节点增加了链接,从而实现了快速的范围查找;

在B+树中,所有记录节点都是按键值的大小顺序存放在同一层的叶子节点上,由各叶子节点指针进行连接。在数据库中,B+树的高度一般都在2~4层,这也就是说查找某一键值的行记录时最多只需要2到4次IO。这很不错,因为当前一般的机械磁盘每秒至少可以做100次IO,2~4次的IO意味着查询时间只需0.02~0.04秒。

什么是覆盖索引?

覆盖索引是指一个索引包含了查询所需的所有字段,而不需要回表查询原始数据。例如,假设我们有一个用户表,包含了用户的id,姓名,年龄,性别等字段,我们想要查询所有年龄大于18岁的用户的姓名和性别,那么我们可以创建一个包含了姓名,性别和年龄的索引,这样就可以直接从索引中获取查询结果,而不需要再访问用户表。

覆盖索引的优点是:

- 减少了磁盘I/O,提高了查询速度

- 减少了内存占用,节省了资源

- 减少了锁的竞争,提高了并发能力,它可以避免回表查询原始数据,从而减少了对数据行的访问和锁定。如果使用索引覆盖,那么只需要对索引记录加锁,而不需要对数据记录加锁。这样就可以减少锁的范围和冲突,提高并发能力

覆盖索引的缺点是:

- 增加了索引的大小,占用了更多的磁盘空间

- 增加了数据更新的开销,因为每次更新数据都需要更新索引

因此,在创建覆盖索引时,我们需要权衡利弊,选择合适的字段和顺序,避免创建过多或过大的索引。

什么是索引下推?

索引下推是指在使用联合索引时,将过滤条件下推到索引层,从而减少回表的次数。
与联合索引不同的是,联合索引只能在查询条件中包含索引的前缀部分时才能生效,而索引下推可以在查询条件中包含任意部分的索引时生效。

在没有使用索引下推的情况下,MySQL的查询:

  • 存储引擎读取索引记录;

  • 根据索引中的主键值,定位并读取完整的行记录;

  • 存储引擎把记录交给Server层去检测该记录是否满足WHERE条件。

使用索引下推的情况下,查询过程:

  • 存储引擎读取索引记录(不是完整的行记录);

  • 判断WHERE条件部分能否用索引中的列来做检查,条件不满足,则处理下一行索引记录;

  • 条件满足,使用索引中的主键去定位并读取完整的行记录(就是所谓的回表);

  • 存储引擎把记录交给Server层,Server层检测该记录是否满足WHERE条件的其余部分。

覆盖索引和索引下推是两种提高数据库查询效率的技术。覆盖索引是指一个索引包含了查询所需的所有字段,而不需要回表查询原始数据。索引下推是指在使用联合索引时,将过滤条件下推到索引层,从而减少回表的次数。

索引的分类(必会)

(1) 普通索引:最基本的索引,它没有任何限制。

黑马程序员·济南校区(2) 唯一索引:与普通索引类似,不同的就是索引列的值必须唯一,但允许有

空值。如果是组合索引,则列值的组合必须唯一。

(3) 主键索引:它是一种特殊的唯一索引,用于唯一标识数据表中的某一条记

录,不允许有空值,一般用

primary key 来约束。

(4) 联合索引(又叫复合索引):多个字段上建立的索引,能够加速复合查询

条件的检索。

(5) 全文索引:老版本 MySQL 自带的全文索引只能用于数据库引擎为

MyISAM 的数据表,新版本 MySQL 5.6 的 InnoDB 支持全文索引。默认 MySQL

不支持中文全文检索,可以通过扩展 MySQL,添加中文全文检索或为中文内容表提供

一个对应的英文索引表的方式来支持中文。

\3. 索引的底层实现原理

1.索引结构

索引是在 Mysql 的存储引擎(InnoDB,MyISAM)层中实现的, 而不是在服务层实现

的. 所以每种存储引擎的索引都不一定完全相同, 也不是所有的存储引擎都支持所有的索引

类型的, Mysql 目前提供了以下 4 种索引:

B+Tree 索引: 最常见的索引类型, 大部分索引都支持 B+树索引.

Hash 索引: 只有 Memory 引擎支持, 使用场景简单.

R-Tree 索引(空间索引): 空间索引是 MyISAM 引擎的一个特殊索引类型, 主要地理

空间数据, 使用也很少.

S-Full-text(全文索引): 全文索引也是 MyISAM 的一个特殊索引类型, 主要用于全

文索引, InnoDB 从 Mysql5.6 版本开始支持全文索引.

2.B树结构

一个m阶B树 (多路 平衡搜索树) 的具有的特征(或必须满足的条件) 如果根节点不是叶子节点,那么它至少有两个节点。

所有叶子节点位于同一层(高度一致)。

除根节点和叶子节点之外,一个节点至少拥有ceil( m / 2)个节点)。

ceil() :向上取整,ceil(3/2)=ceil(1.5)=2

每个叶子节点包含k-1个元素,ceil(m/2)<= k <=m 。

若m=3, 2<=k<=3, 1<=(k-1)<=2,也就是3阶的树叶子节点包含1~2个元素

拥有k个节点的非叶子节点,包含k-1个元素。

B树的查找 如图是一颗3阶B树,满足B树的特征

每层每个节点上都有信息

3.B+Tree 结构

B+Tree 为 BTree 的变种, B+Tree 与 BTree 的区别:

1.B+Tree 的叶子节点保存所有的 key 信息, 依 key 大小顺序排列.

2.B+Tree 叶子节点元素维护了一个单项链表.

所有的非叶子节点都可以看作是 key 的索引部分.

信息都被包含在叶子节点中

由于 B+Tree 只有叶子节点保存 key 信息, 查询任何 key 都要从 root 走的叶子. 所以

B+Tree 查询效率更稳定.

Mysql 中的 B+Tree

MySql 索引数据结构对经典的 B+Tree 进行了优化, 在原 B+Tree 的基础上, 增加

了一个指向相邻叶子节点的链表指针, 就形成了带有顺序指针的 B+Tree, 提高区间访问的

性能.

《YOLOv8实例分割实战:训练自己的数据集 》(视频课程) 本课程将手把手地教大家使用labelme标注和使用YOLOv8训练自己的数据集,完成一个多目标实例分割实战项目。 阅读详情

相关推荐

【机器视觉】Halcon 最新版本安装教程(HALCON 24.11.1.1 Progress-Steady)

注:如果使用评估版本,下载前先了解最新评估授权密钥所支持的版本。。近几年不同版本安装过程类似,均可参考本教程。

OpenSeek的博客 3万+

mysql索引:红黑树、B树、B+树

参考: 微信 知乎 此三者的主要应用是降低大数据量检索时的时间复杂度。 JAVA的hashMap中,当一个桶中的元素个数超过…时,桶内数据的存储结构会由链表改成红黑树。 MySql数据库中,对于数据量超大的数据进行索引时,会采用B+树的存储结构。(索引数据结构的演变:红黑树->B树->B+树) 二叉查找树 对二叉树做中根遍历,数据是有序的,也称二叉排序树、二叉搜索树。 每个节点最...

李思苇 1173

VASP实战:从非共线磁矩到自旋轨道耦合磁各向异性能的完整计算流程解析

本文详细解析了VASP中从非共线磁矩计算到自旋轨道耦合磁各向异性能的完整流程。通过实战案例和参数配置技巧,帮助研究者掌握非线性磁矩计算的关键步骤,包括SOC参数设置、文件传递逻辑以及磁各向异性能的精确提取方法,为材料磁性研究提供实用指导。

weixin_31102231的博客 409

Mysql数据存储原理解析

但是每一个页的存储空间是有限的,如果data数据较大会导致每个节点能存储的key数量很小,当数据量很大的时候,同样会导致树的高度增加,从而增加磁盘IO次数,影响查询效率,这是我们不愿意看到的。在B+Tree中,所有数据记录节点都是按照键值大小顺序存放在同一层的叶子节点上,而非叶子节点上只存储key值信息,这样可以大大加大每个节点存储的key值数量,降低B+Tree的高度。红黑树存储的数据量大的时候,红黑树的节点层数多,也就是树的高度比较高,查找的底层数据时,查找次数就比较多,即。【磁盘I/O操作第3次】

xiaojie_std的专栏 235

window部署open claw(使用wsl-Ubuntu-docker部署)

本文详细介绍了在Windows 11系统下通过WSL2+Docker部署OpenClaw的完整流程。首先需要满足硬件配置要求并开启虚拟化功能,然后依次完成WSL2安装配置、Docker Desktop安装、OpenClaw镜像拉取等步骤。重点说明了端口映射、socat转发配置及openclaw.json文件修改方法。最后通过验证WSL2内网IP和端口访问服务。该方案具有最佳兼容性,能有效避免Windows环境下的依赖冲突问题。

Kmoyic的博客 2763

DL-FWI基础入门培训视频学习1、2

DL-FWI基础知识

shengMio的博客 709

mysql的底层数据结构组成

定义:本身就是一种特殊的二叉树,每个节点上都有存储位表示节点的颜色,可以是red或black 约束:每个节点是黑色或者红色,根节点为黑色,叶子节点(特指空节点)是黑色,每个红色节点的子节点都是黑色的,任何一个节点到其每一个叶子节点的所有路径上黑色节点数相同 特点:速度特别快,趋近平衡树,查找叶子元素最少和最多次数不多余二倍。B树(B-tree)每个节点都存放了真实的数据,mysql一个根节点数据存储为16KB,会导致每一个节点存储的数据量变小,所以B树的高度会变高,维护的代价大,查询修改性能会越来越低。

m0_70208894的博客 1326

ADS2023实战:手把手教你用Load-Pull设计40W LDMOS功率放大器(附工程文件)

本文以飞思卡尔MRF8P9040N LDMOS晶体管为例,详细介绍了在ADS 2023中设计一款40W功率放大器(PA)的全流程。内容涵盖从直流偏置设置、稳定性分析、核心的负载牵引(Load-Pull)仿真,到基于Smith圆图的匹配网络设计、谐波平衡性能验证,直至版图生成与优化。文章提供了手把手的实战指导和工程文件,旨在帮助射频工程师掌握高效率PA的设计方法与关键技巧。

cake8的博客 1071

B树与B+树

一、B树 1.B树的优点 B树是一种特殊的平衡树,他相比于平衡二叉树来说一个节点能容纳的元素更多,树的高度更低,搜索次数更少。再一次磁盘访问中能读取到的元素就更多,减少了IO访问次数,提升了数据读写的效率。 2.B树特性 1.所有叶子节点都在都在同一层 2.根节点元素数量:1<=n<=阶数-1,非根节点元素个数 :阶数除二(整除)<=n<=阶数-1 3.除了根节点可能没有子节点这种特殊情况外,每个节点的子节点数量为当前节点元素个数+1 4.每个节点中的元素按一定顺序排列,同时这

qq_44376432的博客 349

Django 小实例S1 简易学生选课管理系统 —— 〇、初步介绍与演示

python Django实现的一个简易的教务选课系统。 介绍与演示的视频版本已发到我的b站: https://www.bilibili.com/video/BV1er4y1w7ty。 项目已上传到我的github: https://github.com/BigShuang/SimpleStudentCourseManagementSystem。 S1总目录: 〇、初步介绍与演示 一、项目流程梳理与数据库设计 ======================= 大爽歌作,made by big shuang.

大爽老师的博客 5944

Trae的付费之路还挺艰难,茫茫多的人想付付不了(附解决办法)

不得不说,Trae国际版这个付费其实整的挺复杂的,但没办法,毕竟有政策限制,付费成功后,你就是尊贵的Pro用户啦,使用Claude 4不排队还是挺爽的,而且600次其实不算少了,有一个小技巧,简单的问题就把模型切到Gemini-2.5-flag,因为使用这个模型是没有次数限制的。其次付费的时候有个ZIP Code,这东西也是个迷之存在,有的地区节点需要填,有的不需要,如果你选到了不需要填的节点,那很好,付费就行了,如果需要填,可以填一个51800试试。

cpp加油站的专栏 5879

【MySQL】索引

介绍索引,建立MySQL与磁盘交换的基本单位的共识,深入理解索引,最后进行索引操作!

YoungMLet的博客 6501

【Windows Server 2019】邮件服务器配置与管理——安装及配置Winmail服务器(上)

博文介绍了如何安装邮件服务器 Winmail,如何配置Winmail,包括运行服务器,Winmail管理工具介绍和域名配置。

VMware, Windows, Linux, Cisco, Container, Kubernetes, Kali 2万+

MySQL —— 索引

介绍MySQL 的索引,索引的运作流程分析,索引的创建修改以及删除。

熵减玩家 3262

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

MySql 索引

MySql 索引底层原理和实现,MySql索引创建,删除,使用。

2301_76293625的博客 2307

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

MySQL——索引

MySQL、索引

2303_78442132的博客 1750

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

mysql 创建聚集索引_MySQL 索引

目录1、索引原理2、索引分类(Index Class)3、索引操作4、索引使用策略5、总结来源:segmentfault.com/a/1190000014906118#item-51、索引原理我们知道,MySQL 查询数据是从第一条记录开始依次查找,直到读完整个表或者找到匹配的行。数据库表的数据量越大,MySQL 查询所花费的时间就越多。索引的出现就是为了改善查询性能的。MySQL 官...

weixin_39760206的博客 4765

mysql索引年龄索引_MySQL索引

1.提升查询效率类似字典,比如:年龄为20的都在第几页,把20和页码都存放在索引中下一次查询时,不从第一页,一条一条的查询,而是根据索引信息快速的查询出数据。索引本身也要耗费存储空间的,跟字典中的拼音查询、部首查询占字典的页数一样。2.其他的增删改,效率降低索引还会浪费增删改效率,除了查询效率高了以外,其他的增删改效率都低了。(数据页的数据改动也需要改动索引页相对应的数据)3.MySQL索引类型3...

weixin_42631411的博客 1320

Mysql的索引

在mysql中,索引是一种特殊的数据库结构,由数据表中的一列或多列组合而成,可以用来快速查询数据表中有某一特定值的记录。通过索引,查询数据时不用读完记录的所有信息,而只是查询索引列即可。什么是mysql索引。

jdbcmeng的博客 1049
上一篇: org.apache.ibatis.binding.BindingException错误
下一篇: 依赖循环 com.github.pagehelper.autoconfigure.PageHelperAutoConfigurationy
一只会叫的兽
博客等级 码龄3年 117粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值