MySQL-B+树索引结构

1、存储单元
  • 磁盘:最小单元是扇区,一个扇区的大小是 512个字节

  • 文件系统:最小单元是块,一个块的大小是 4K

  • InnoDB存储引擎:最小单元称之为页,一个页的大小是16K

2、B+树存储结构

mysql数据库中,table表中的记录都是存储在页中。假如一行数据的大小约为1K字节,那么按 16K / 1K = 16,可以计算出一页大约能存放16条数据。

B+树存储结构如图所示:

数据页除了可以存放数据(叶子节点),还可以存放健值和指针(非叶子节点),当然他们是有序的。这样的数据组织形式,我们称为索引组织表。

B+ 树是如何检索记录?

  • 首先找到根页,其实每张表的根页位置在表空间文件中是固定的,即page number=3的页
  • 找到根页后通过二分查找法,定位到id=5的数据应该在指针P5指向的页中
    然后再去page number=5的页中查找,同样通过二分查询法即可找到id=5的记录。

查看指定表的索引信息

mysql> SELECT b.name, a.name, index_id, type, a.space, a.PAGE_NO FROM information_schema.INNODB_SYS_INDEXES a, information_schema.INNODB_SYS_TABLES b WHERE a.table_id = b.table_id AND a.space <> 0 and b.name like '%ada%';
3、计算B+树的高度

3.1 查询表中index ID 和 page number信息

mysql> select b.NAME, a.NAME, a.INDEX_ID, a.PAGE_NO from information_schema.innodb_indexes as a join information_schema.innodb_tables as b on a.table_id=b.table_id;
+-----------------------+-----------------+----------+---------+
| NAME                  | NAME            | INDEX_ID | PAGE_NO |
+-----------------------+-----------------+----------+---------+
| test/t1               | i_id            |      163 |       5 |
| test/t1               | GEN_CLUST_INDEX |      162 |       4 |
+-----------------------+-----------------+----------+---------+
2 rows in set (0.00 sec)

3.2 ibd文件存储格式

某个表的idb文件是按照page页,一块一块存储的,innodb引擎默认 page 页大小16k。

查看表 t1 的 ibd 文件大小

[root@localhost test]# ll -h t1.ibd 
-rw-r----- 1 mysql mysql 128K 112 21:31 t1.ibd

通过 ibd 文件大小可知,一共有 128k/16k=8 page页

innodb引擎 page 页结构图

3.3 计算某一个表中索引高度

在 3.1 中查询到表 t1 的 i_id 索引所在的 page number 是 5,在 ibd 文件中 page 页是从 0 开始计算的,所以 i_id 索引信息保存在第 6 个 page 页中。从 3.2 结构中,可知在页头的 page_level 和 page_index_id 位置。

通过hexdump操作系统命令分析ibd文件,查看索引高度。

查看hexdump命令选项用法:

[root@localhost test]# hexdump --help
 -n 长度         只解释输入的指定长度个字节
 -s 偏移         跳过开头指定长度个字节

计算索引高度,偏移量offset=16k*5+38(文件头字节数)+26(页头跳过的字节数)=81984 Byte

通过如下命令可知,在 ibd 文件中存储的信息,以16进制表示。

[root@localhost test]# hexdump -s 81984 -n 10 t1.ibd 
0014040 0000 0000 0000 0000 a300               
001404a

可知 page_level(2字节)是 0000 。所以该索引高度为 1 。

page_index_id(8字节)是 0000 0000 0000 a300 ,转换10进制为163,和 3.1 中查询结果一致。

4、一颗B+树可以存放的数据量

假设B+树的深度为2

这棵B+树的存储总记录数 = 根节点指针数 * 单个叶子节点记录条数

那么指针数如何计算?

假设主键ID为bigint类型,长度为8字节,而指针大小在InnoDB源码中设置为6字节,这样一共14字节。

那么一个页中能存放多少这样的组合,就代表有多少指针,即 16384 / 14 = 1170。那么可以算出一棵高度为2 的B+树,能存放 1170 * 16 = 18720 条这样的数据记录。

同理:

高度为3的B+树可以存放的行数 = 1170 * 1170 * 16 = 21902400

posted @   原来是你~~~  阅读(292)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程
点击右上角即可分享
微信分享提示