如何理解Mysql的索引及他们的原理--------二叉查找树和平衡二叉树和B树和B+树

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用版 2核4GB 50GB
简介: 如何理解Mysql的索引及他们的原理--------二叉查找树和平衡二叉树和B树和B+树

1.索引是什么东西?

索引就是一个数据结构,我们把表中的记录用一个适合高效查找的数据结构来表示,目的就是让查询变得更高效。

2.它到底怎么运作的?

这个问题就说来话长了,且听我慢慢道来:

在mysql中使用最广泛的数据引擎是InnoDB 引擎,它里面用的是 B+ 树索引。

我们重点分析一下这个索引的原理:

要想理解B+树索引要先从 二叉查找树,平衡二叉树和 B 树说起因为B+树索引就是由他们演化而来:

在mysql中使用最广泛的数据引擎是InnoDB 引擎,它里面用的是 B+ 树索引。

我们重点分析一下这个索引的原理:

要想理解B+树索引要先从 二叉查找树,平衡二叉树和 B 树说起因为B+树索引就是由他们演化而来:

什么是二叉查找树?

 

满足这样条件的就叫二叉查找树:

每个节点左边节点的值都小于该节点,右边节点的值都大于该节点,没有值相等的节点,最顶端的节点也就是“45”被称为根节点。

二叉查找树的查找过程:

若根结点的值等于查找的值,成功,

否则,若小于根结点的值,递归查左子树(也就是根节点左边的所有节点形成的树)

若大于根结点的值,递归查右子树(也就是根节点右边所有节点形成的树)。

假设用二叉查找树创建book表的索引:

索引如下:

图一

此处的bid为主键,每个节点存储了主键的值和该条记录的内容。

如果我要查找bid为6的图书的信息,则先用6和根节点的主键值7比较发现比7小,

然后6再和7左边的节点5比较发现比5大找到5右边的节点6,找到了,取出6对应的记录行的值ee.

总共经历了3次比较,如果扫描全表需要经过5次比较。

什么是平衡二叉树?

如果索引是这样:

图二

想要找到主键键值为9的记录就需要6次比较,索引的优势完全体现不出来。


为什么会这样?原因就在于这棵树太高了,如果能想办法把它变得矮一点,胖一点就完美了。于是平衡二叉树闪亮登场:


平衡二叉树首先也是一个二叉树,需要满足二叉树的所有条件,然后有所改进,规定了左右子树的高度差不能超过1,如果插入数据导致高度差超过了1则自动进行调整,回复到平衡状态。这也是平衡二叉树名字的由来。


图一就是一颗平衡二叉树,图二根节点的左子树高度为0,右子树高度为5,高度差是5超过了1所以不是一颗平衡二叉树。


平衡二叉树查找效率要高于二叉树。

什么是B树?

由前面的推导我们可以看出要想查找,比较的次数最少,必须想办法降低树形结构的高度,不管是二叉树还是平衡二叉树,每个节点最多只能有两个子节点,这就注定了它的高度受限于子节点的个数,于是B树横空出世.


从上图可以看到B树的节点可以不止两个子节点,这样的好处就是树可以变得又矮又胖,矮胖的树是索引的最爱,用它做索引可以降低磁盘的IO.


B树中的每个节点根据实际情况可以包含大量的键值,数据和指针,上图所示为一个3阶的B树:


每点占用一个磁盘块的磁盘空个节间,一个节点上有两个升序排序的键值和三个指向子树根节点的指针,指针存储的是子节点所在磁盘块的地址。两个键值划分成的三个范围域对应三个指针指向的子树的数据的范围域。以根节点为例,键值为17和35,P1指针指向的子树的数据范围为小于17,P2指针指向的子树的数据范围为17~35,P3指针指向的子树的数据范围为大于35。


模拟查找关键字29的过程:


根据根节点找到磁盘块1,读入内存。【磁盘I/O操作第1次】


比较关键字29在区间(17,35),找到磁盘块1的指针P2。


根据P2指针找到磁盘块3,读入内存。【磁盘I/O操作第2次】


比较关键字29在区间(26,30),找到磁盘块3的指针P2。


根据P2指针找到磁盘块8,读入内存。【磁盘I/O操作第3次】


在磁盘块8中的关键字列表中找到关键字29。


分析上面过程,发现需要3次磁盘I/O操作,和3次内存查找操作。由于内存中的键值是一个有序表结构,可以利用二分法查找提高效率。而3次磁盘I/O操作是影响整个B树查找效率的决定因素。

什么是B+树?

想想还有没有可能进一步优化,在B树中每个节点的内容由三部分组成:键值,指针,数据,而磁盘块的容量是有限的,并不是每次读取磁盘块都会取出里面的数据,只是在最后一次读取的时候才会取出里面的数据,能不能将数据只存储在叶子节点里面,非叶子节点只存储键值和指针呢?这样就能最大化的利用磁盘块空间,一个磁盘块也就能存更多的东西了,没错,B+树就是这么干的

假设在非叶子节点不存数据以后每个节点可以存储4个键值和指针,就变成了上图的B+树

B+树相对于B树有几点不同:

  1. 非叶子节点只存储键值和指针。
  2. 所有叶子节点之间都有一个链指针。
  3. 数据记录都存放在叶子节点中。

在B+树中因为叶子节点的键值是按顺序排列的所以进行键值的范围查找效率非常高。

在B+树中由于一个节点存储了更多的键值和指针,所以同样多的内容可以降低树的高度,减少磁盘io次数,从而提高效率。


数据库的索引分为聚集索引和非聚集索引,innoDb存储引擎中的聚集索引表中的数据按主键的顺序存放,它实际上就是按主键构建的一个B+树,叶子节点存放的是数据行记录。所以数据库中的数据实际上是索引的一部分。由于实际的数据页只能按照一个顺序存放,所以每张表聚集索引只能有一个。


非聚集索引的叶子节点中存放的是键值和主键值,所以通过非聚集索引需要先查找到主键值然后通过聚集索引查询到具体的数据,因此非聚集索引的效率要低于聚集索引。非聚集索引并不会影响到数据的存储顺序,所以非聚集索引可以存在多个。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3天前
|
SQL 存储 关系型数据库
mysql加索引真的会锁表吗?揭秘背后的技术细节与规避策略
【8月更文挑战第16天】在数据库管理中,添加索引能大幅提升查询效率。MySQL执行此操作时的锁定行为常引起关注。文章详细解析MySQL中索引添加时的锁定机制及其原理。不同存储引擎及SQL语句影响锁定策略:MyISAM需全表锁定;InnoDB提供更灵活选项,如使用`ALTER TABLE... LOCK=NONE`可在加索引时允许读写访问,尽管可能延长索引构建时间。自MySQL 5.6起,在线DDL技术可进一步减少锁定时间,通过`ALGORITHM=INPLACE`和`LOCK=NONE`实现近乎无锁的表结构变更。合理配置这些选项有助于最小化对业务的影响并保持数据库高效运行。
11 4
|
3天前
|
SQL JavaScript 关系型数据库
Mysql索引不当引发死锁问题
本文通过真实案例解析了MySQL在高并发环境下出现死锁的问题。数据库表`t_award`包含多个索引,但在执行特定SQL语句时遭遇索引失效,导致更新操作变慢并引发死锁。分析发现,联合索引`(pool_id, identifier, status, is_redeemed)`因`identifier`允许为空值而导致索引部分失效。此外,`pool_id`上的普通索引产生的间隙锁在高并发下加剧了死锁风险。为解决此问题,文中提出了调整索引顺序至`(pool_id, status, is_redeemed, identifier)`等方案来优化索引使用,进而减轻死锁现象。
|
5天前
|
缓存 NoSQL Redis
一天五道Java面试题----第九天(简述MySQL中索引类型对数据库的性能的影响--------->缓存雪崩、缓存穿透、缓存击穿)
这篇文章是关于Java面试中可能会遇到的五个问题,包括MySQL索引类型及其对数据库性能的影响、Redis的RDB和AOF持久化机制、Redis的过期键删除策略、Redis的单线程模型为何高效,以及缓存雪崩、缓存穿透和缓存击穿的概念及其解决方案。
|
8天前
|
存储 关系型数据库 MySQL
"揭秘!MySQL为何独宠B+树?跳表再牛,也敌不过这性能王者的N重诱惑!"
【8月更文挑战第11天】MySQL作为主流关系型数据库,优选B+树而非跳表作为索引结构,基于其对范围查询的支持、低磁盘I/O开销及事务处理能力。B+树叶节点构成有序链表,利于范围查询;较矮的树形结构减少了磁盘访问次数;支持多版本并发控制,保障事务ACID特性。而跳表在线性扫描范围查询时效率低,难以高效实现事务管理,且额外指针增加空间消耗。示例代码展示了B+树节点分裂过程,突显其内部机制。综上,B+树为MySQL提供了高性能、可靠的数据存储与检索能力。
21 4
|
9天前
|
存储 关系型数据库 MySQL
MySQL为何偏爱B+树而非跳表?
【8月更文挑战第9天】在数据库的世界里,索引是提升查询效率的关键。而在MySQL这样的关系型数据库管理系统中,B+树作为索引结构的首选,其背后的原因值得我们深入探讨。本文将从技术角度解析,为何MySQL选择B+树而非跳表作为其索引结构的核心。
36 1
|
5天前
|
存储 关系型数据库 MySQL
MySQL——数据库备份上传到阿里云OSS存储
MySQL——数据库备份上传到阿里云OSS存储
18 0
|
8天前
|
SQL 存储 关系型数据库
"MySQL增列必锁表?揭秘InnoDB在线DDL,让你的数据库操作飞一般,性能无忧!"
【8月更文挑战第11天】在数据库领域,MySQL凭借其稳定高效的表现深受开发者喜爱。对于是否会在给数据表添加列时锁表的问题,MySQL的行为受版本、存储引擎等因素影响。从5.6版起,InnoDB支持在线DDL,可在改动表结构时保持表的可访问性,避免长时间锁表。而MyISAM等则需锁表完成操作。例如,在使用InnoDB的表上运行`ALTER TABLE users ADD COLUMN email VARCHAR(255);`时,通常不会完全锁表。虽然在线DDL提高了灵活性,但复杂操作或大表变更仍可能暂时影响性能。因此,进行结构变更前应评估其影响并择机执行。
29 6
|
7天前
|
Oracle 关系型数据库 MySQL
Mysql和Oracle数据库死锁查看以及解决
【8月更文挑战第11天】本文介绍了解决MySQL与Oracle数据库死锁的方法。MySQL可通过`SHOW ENGINE INNODB STATUS`查看死锁详情,并自动回滚一个事务解除死锁;也可手动KILL事务。Oracle则通过查询V$LOCK与V$SESSION视图定位死锁,并用`ALTER SYSTEM KILL SESSION`命令终止相关会话。预防措施包括遵循ACID原则、优化索引及拆分大型事务。
|
8天前
|
固态存储 关系型数据库 MySQL
"惊!20亿数据秒速入MySQL,揭秘数据库极速插入的黑科技,你不可不知的绝密技巧!"
【8月更文挑战第11天】面对20亿级数据量,高效插入MySQL成为挑战。本文探讨优化策略:合理设计数据库减少不必要的字段和索引;使用批量插入减少网络往返;优化硬件如SSD和内存及调整MySQL配置;并行处理加速插入;附Python示例代码实现分批导入。这些方法将有效提升大规模数据处理能力。
23 2
|
10天前
|
存储 关系型数据库 MySQL
"Linux环境下MySQL数据库名及表名大小写敏感性设置详解:从配置到影响,确保数据库操作的准确与高效"
【8月更文挑战第9天】在Linux环境中,MySQL数据库名及表名的大小写敏感性是一项重要配置。默认情况下,MySQL在Linux上区分大小写,但这可通过配置文件 `/etc/my.cnf` 中的 `lower_case_table_names` 参数调整。该参数设为0时,名称存储时保持原样,查询时不区分大小写;设为1则全部转换为小写。通过编辑配置文件并重启MySQL服务,可根据需求灵活控制名称的大小写敏感性,确保数据一致性和应用兼容性。
26 3