mysql-索引1

一 简介

MySql的索引是一种数据结构。它可以帮助数据库高效地查询、更新数据表中的数据。它类似于书籍的目录,通过指向数据行的位置,可以快速定位和访问表中的数据。

那为什么使用索引呢?

主要就是提升数据检索的效率

刚才提到索引是一种数据结构,那它选择的是哪种数据结构呢?让我们一个一个地来看一下吧

二 索引数据结构的选择

1 HASH

它的时间复杂度是O(1),感觉非常适合。但是它不支持范围查找

2 二叉搜索树

它支持范围查找,但它的时间复杂度在单边树的时候为O(N) ,因为节点个数过多时,树的高度无法保证,磁盘IO的次数就会变得很多。因为数据库中的数据都是在磁盘上保存的,每访问一次子节点,就会发生一次磁盘IO,磁盘IO是制约数据库性能的主要因素

3 N叉树

它的每个节点可以有超过两个的子节点,可以解决树高的问题。它的时间复杂度是O(logN),在数据量相同的情况下,可以有效的控制树高,也就是说可以使用更少的IO次数找到目标节点,从而提高数据库的效率。但是这个还是不够好,看看下一个(下一个更乖,哈哈)

比如:

4 B+树

B+树是一种经常用于数据库和文件系统等场合的平衡查找树,这就是MySql索引采用的数据结构。它的时间复杂度也是O(logN),可以有效的控制树高

比如:

它的特点如下:
能够保持数据稳定有序,插⼊与修改有较稳定的时间复杂度
⾮叶⼦节点仅具有索引作⽤,不存储数据,所有叶⼦节点保真实数据
所有叶⼦节点构成⼀个有序链表,可以按照key排序的次序依次遍历全部数据
上面的两个树有什么区别?(重点)
对于B+树而言:
1)叶子节点之间有一个相互连接的引用(看图),可以通过一个叶子节点找到它相近的兄弟节点。MySql在组织叶子节点时使用的是双向链表(上面的图是单向的,应该是双向的)。
2)非叶子节点的值都包含在叶子节点中。MySql非叶子节点只保存了对叶子节点的引用,并没有保存真实的数据,所有真实的数据都保存在叶子节点中。
3)对于B+树而言,在相同树高的情况下,查找任意元素的时间复杂度都一样,性能均衡
要想知道索引在整个数据检索的过程中是如何工作的,得从MySql存储结构说起:

三 MySql中的页

1 简介

在 .ibd ⽂件中最重要的结构体 就是Page(⻚),⻚是内存与磁盘交互的最⼩单元,默认⼤⼩为
16KB,每次内存与磁盘的交互⾄少读取⼀⻚,所以在磁盘中每个⻚内部的地址都是连续的,之所
以这样做,是因为在使⽤数据的过程中,将来要使⽤的数据⼤概率与当前访问的数据在空间上是临近的,所以⼀次从磁盘中读取⼀⻚的数据放⼊内存中,当下次查询的数据还在这个⻚中时就可以从内存中直接读取,从⽽减少磁盘I/O提⾼性能。
其中,那个.ibd文件就是innodb存储引擎生成的
空间文件
每个页中即使没有数据也会使用16KB的存储空间,同时与索引的B+树中的节点对应
比如:

查看页大小

详解:
在MySQL中有多种不同类型的⻚,最常⽤的就是⽤来存储数据和索引的"索引⻚",也叫做"数据
",但不论哪种类型的⻚都会包含⻚头(File Header)和⻚尾(File Trailer),⻚的主体信息使⽤数
据"⾏"进⾏填充。
这里只介绍数据页(索引页),数据⻚的基本结构如下图所⽰:

独立表空间文件是每创建一张表生成一个保存数据的文件

2 页文件头和页文件尾

表示当前页文件的主要信息。这里只关注,上一页页号和下一页页号,通过这两个属性可以把页与页之间连接起来,形成一个双向链表(通过页号和页大小,可以计算出下一页和上一页在磁盘上的偏移量)

3 页主体

页主体是保存真实数据的主要区域,每当创建一个新页,都会自动分配两个行,一个是页内最小行Infimun,另一个是页内最大行 Supremun,这两个行并不存储任何真实信息,而是作为数据行链表的头和尾 ,第一个数据行有一个记录下一行的地址偏移量的区域next_record,将页内所有数据行组成了一个单向链表,新页(没有数据)结构如下:

此时,插入数据时,将Infimun连接第一个数据行,最后一行真实数据行连接Supremun,这样数据行 就成了一个单向链表,更多的行插入之后,会按照主键从小到大的顺序进行连接

图:

这是就会有疑问了:单向链表,数据过多的时候,查起来的时候也麻烦,怎么办呢?

页目录:

4 页目录

在每一个页中加入页目录的结构,将页内所有行进行分组,其中,最小行单独为一组,其他每个组最多8条数据,超过8条时会分裂出来一个新组,最大行永远在最后一个分组中。同时把每个组最后一行在页中的地址,按主键从小到大的顺序记录在页目录中,页目录中的每一个位置称为一个槽,槽的数量与分组的数据是一致的


比如查找主键为6的行:
1)找到这条记录所在的页、
2)在页中找到所在的槽
3)在分组中找到对应的记录

5 数据页头

记录了当前页保存数据相关的信息

6 B+树在索引中的应用

索引页保存的是主键的值和子节点的引用,非叶子节点记录的是索引信息

叶子节点存储的是真实数据,数据页保存的是具体数据,叶子节点最终形成了一个双向循环链表

值得注意的是,所有关于页的访问和操作都是在内存中进行的

加载索引页1 -> 加载索引页2 -> 加载数据页3 就是3次IO

OK啦!!!!

相关推荐
叶 落1 小时前
Ubuntu24 安装 PostgreSQL
数据库·postgresql·安装教程
HAYDENR1 小时前
依赖数据迁移工具做增量同步有哪些易错点?调整数据迁移工具策略怎么保证断点续传可靠?
java·大数据·数据库
邀星月为媒1 小时前
高阶加餐 08|Prompt 故障定位与可观测性:模型突然变差时,别再靠“重新写一遍 Prompt”解决
服务器·数据库·prompt
2501_937860944 小时前
MySQL表的操作:创建、查看、修改、删除完整实战
android·数据库·mysql
奇特認8 小时前
mysql 集群技术 3.高可用之 MHA
数据库·mysql
Bioinfo Guy10 小时前
高分Panel复现系列|转录因子网络太乱?用模块框把重点圈出来
数据库·生物信息学·生信可视化
ltl12 小时前
Disaggregated DB 合集:Socrates、PolarDB、Taurus 的共同模式
数据库
Blossom i14 小时前
大数据预处理与采集实验一:使用Python操作MySQL数据库
数据库·mysql
InfinitePlus14 小时前
Docker MySQL搭建一主一从
mysql·docker