MySql Innodb 索引 B+Tree

本文介绍了B+树作为数据库索引的基础,详细阐述了B+树的结构特点,包括其非叶子节点不存储数据记录、叶子节点包含所有指针等特性。B+树的优势在于更高的数据存储密度、更少的磁盘IO次数和稳定的查询性能。此外,还提及了MySQL中InnoDB引擎的页管理和行格式,特别是COMPACT行格式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

索引的目的

B+Tree索引

B+Tree索引
B+树是由二叉查找树、平衡二叉树(AVLTree)和平衡多路查找树(B-Tree)逐步优化而来。

二叉查找树的任意一个节点,其左子树的每个节点的值都要小于这个节点的值,而右子树节点的值都应大于这个节点的值。
这种结构有利于快速查找一个数据。

平衡二叉树(AVL树)在符合二叉查找树的条件下,还满足任何节点的两个子树的高度最大差为1。解决了二叉查找树发生倾斜
而造成查询效率减低的问题,但同时带来了维持平衡的成本,在增加和删除节点时要通过旋转来保持树的平衡。

B-Tree是为磁盘等外存储设备设计的一种平衡查找树。当数据非常大时,内存不够用,大部分数据只能存放在磁盘上,只有需要的数据才加载到内存中,内存访问的时间比磁盘快一个等级。所以减少磁盘IO次数能够增加索引速度,B树多路的好处就是可以将多个关键字组成一个节点,有效的减低了B树的高度,每一个节点确定的范围更广也更精确,增加了缩小索引范围的速度。

B树的特点是能够保持数据稳定有序,其插入与修改拥有较稳定的对数时间复杂度。 B+ 树元素自底向上插入。

B+树的主要特征:

1,索引关键字从左到右递增排序,非叶子结点关键字比其左边的指针指向的子节点都大,比其右边的关键字都小。
2,B+树的非叶子节点不保存关键字记录的指针,只进行数据索引,这样使得B+树每个非叶子节点所能保存的关键字大大增加;
3,B+树叶子节点保存了父节点的所有关键字记录的指针,所有数据地址必须要到叶子节点才能获取到。所以每次数据查询的次数,都一样;

4,B+树叶子节点的关键字从小到大有序排列,左边结尾数据都会保存右边节点开始数据的指针。 非叶子节点的子节点数=关键字数。

B+树相比B树的优势:

1,每个节点存储的关键字更多,树的高度更低,查询时磁盘IO次数更少。

2,所有查询都必须找到叶子节点,查询性能更稳定。

3,所有叶子节点形成有序双链表,便于范围查找。

聚集索引

非聚集索引

innodb_file_per_table在mysql5.6.6及其后续版本默认开启,开启该参数的时候,Innodb将每个新创建的表的数据及索引存储在一个独立的.ibd文件里。

.ibd文件是使用InnoDB引擎的表产生的索引和数据文件。每个表还对应一个.frm文件,描述了表的格式。

(如果引擎使用的是MyISAM的话,会产生索引和数据分开存放的两个文件,.MYI(索引文件)和.MYD(数据文件))

页是InnoDB磁盘管理的最小单位,默认每个页的大小为16KB。

B+树索引里的非叶子节点和叶子节点对应存储关键字的页和存储数据的页。

MySql中数据是按照行进行存取的,即页中保存着表里的一行行的数据。innodb一共有四种行格式,分别是:compact、redundant、dynamic、compressed。

每种格式原理上大体相同,这里只介绍COMPACT行格式。

### MySQL B+Tree 素引工作原理 #### 一、B+Tree 的基本特性 B+Tree 是一种多路搜索,其设计目的是为了减少磁盘I/O操作次数。与普通的二叉查找不同,在B+Tree中: - 所有记录节点都位于叶子结点上; - 非叶节点仅保存关键字及其指向子的指针; - 叶子节点之间存在链表连接,方便范围扫描。 这种结构使得每次访问都能定位到具体的页位置,并且可以快速遍历相邻的数据项[^1]。 #### 二、InnoDB 中 B+Tree 实现特点 在 InnoDB 存储引擎里实现了自己的版本——即所谓的“聚簇索引”。这意味着每张表都有一个唯一的聚集索引(通常是主键),其他辅助索引则会引用这个聚集索引来间接存取实际行数据。当创建一个新的非唯一二级索引时,它实际上是由两部分组成:一部分用于存储该列上的值;另一部分则是对应于这些值所在行的位置信息(也就是主键值)[^4]。 #### 三、查询过程解析 假设有一个基于整数ID建立起来的标准B+Tree索引,当我们执行如下SQL语句 `SELECT * FROM table WHERE id=5;` ,整个检索流程大致如下所示: 1. **根节点读入缓存区** 查询开始前先加载根节点至缓冲池内。 2. **比较并向下层推进** 对当前节点内的所有key进行线性查找,找到第一个大于等于目标id的关键字k_i,接着转向对应的分支继续探索直到达到最底层为止。 3. **命中或未命中的处理** 如果最终落在某个leaf node里面找到了匹配条目,则返回相应结果集给客户端程序;反之如果找不到任何符合条件的结果就报错提示用户不存在这样的记录[^2]. ```sql EXPLAIN SELECT * FROM t_user WHERE user_id = '007'; ``` 上述命令可以帮助开发者查看具体某次select操作所走过的路径以及涉及到哪些index pages.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值