当前位置:网站首页>MySQL索引的B+树到底有多高?
MySQL索引的B+树到底有多高?
2022-08-09 15:33:00 【InfoQ】
一、问题
- h:统称索引的高度;
- h1:聚簇索引的高度;
- h2:二级辅助索引的高度;
- k:中间结点的扇出系数。
二、分析

2.1 索引高度h与页面I/O数的关系
SELECT * FROM USER WHERE id=1
- 点查询: 聚族索引:h1 二级索引: 覆盖索引:h2 回表查询:h2+h1
- 范围查询:这种情况相对比较复杂,但跟点查询的原理类似,读者可自行分析;
- 全表查询:B+树的叶子结点是通过链表连接起来的,对于全表查询,需要从头到尾将所有的叶子结点访问一遍。
2.2 索引高度h的理论计算
k^(h-1)
k^(h-1)*n
三、查看索引真实高度的方法

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;
复制代码

hexdump
$hexdump -C -s 49216 -n 10 user.ibd
0000c040 00 01 00 00 00 00 00 00 03 2b
复制代码
16384*3+64
- 通过
information_schema.INNODB_SYS_INDEXES
和 information_schema.INNODB_SYS_TABLES
找到对应索引Root页在ibd文件的页面号PAGE_NO(聚簇索引通常为3,其他索引往上累加);
- 通过
hexdump -C -s 16384*PAGE_NO+64 -n 10 user.ibd
,前两个字节+1即为索引的高度。
四、验证索引的真实高度
CREATE TABLE `user` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`card_id` INT(11) NOT NULL DEFAULT '0' COMMENT '身份证号',
`name` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '英文名字',
`age` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0' COMMENT '年龄',
`content` VARCHAR(1024) NOT NULL DEFAULT '' COMMENT '附属信息',
`create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最近更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uniq_card_id` (`card_id`),
KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
复制代码
card_id
name
content

hexdump -C -s 49216 -n 10 user.ibd && hexdump -C -s 65600 -n 10 user.ibd && hexdump -C -s 81984 -n 10 user.ibd
idx_name
name
五、总结
- 一次查询的页面I/O数跟索引高度h呈正相关,主要分为以下几种情况:
- 点查询: 聚族索引:h1 二级索引: 覆盖索引:h2 回表查询:h2+h1
- 范围查询:这种情况相对比较复杂,但跟点查询的原理类似,读者可自行分析;
- 全表查询:B+树的叶子结点是通过链表连接起来的,对于全表查询,需要从头到尾将所有的叶子结点访问一遍。
- 索引高度通常为2~4层。在高度h=3、主键为int类型、行记录大小为1KB时,可索引的总行数为1170^2*16=2190W。这也是 很多大厂将2000W作为分库分表标准 的原因;
- 查看索引真实高度的方法如下:
- 通过
information_schema.INNODB_SYS_INDEXES
和 information_schema.INNODB_SYS_TABLES
找到对应索引Root页在ibd文件的页面号PAGE_NO(聚簇索引通常为3,其他索引往上累加); - 通过
hexdump -C -s 16384*PAGE_NO+64 -n 10 user.ibd
,前两个字节+1即为索引的高度。
- 索引高度h也跟索引字段的数据类型有关。如果是int或short,扇出系数大,索引效率更好,整个索引看起来属于“矮胖”型;而如果是varchar(32)等,那扇出系数就低了,整个索引看起来属于“瘦高”型,索引效率自然要低些。所以我们在字段选取类型时,其 类型越简单效率越好 。
#聚簇索引(第一个)
hexdump -C -s 49216 -n 10 user.ibd
#第二个索引
hexdump -C -s 65600 -n 10 user.ibd
#第三个索引
hexdump -C -s 81984 -n 10 user.ibd
复制代码
边栏推荐
- Access Characteristics of Constructor under Inheritance Relationship
- 为什么四个字节的float表示的范围比八个字节的long要广
- Smart Light Pole Gateway Smart Transportation Application
- 三.两数交换 空指针 && 野指针 解引用问题
- 如何判断闰年
- 易基因|作物育种:DNA甲基化在大豆优良品种培育中的作用研究成果
- BETA:一个用于计算药物靶标预测的综合基准
- 2. Creating Interactive Maps
- DP 优化方法合集
- Anatomy of Storage Size, Value Range, and Output Format of Basic Data Types in C Language
猜你喜欢
Detailed explanation of three pieces in C language
微服务框架笔记(1)
开源星「001 号」落地 FlyFish,欢迎登陆赢神秘大礼包!
uniapp 项目搭建
网络——虚拟专用网和地址转换NAT
character rhombus code
给我一个机会,帮你快速上手三子棋
ECCV 2022 | BMD: 面向无源领域自适应的类平衡多中心动态原型策略
[Server data recovery] Data recovery case of file system data loss caused by SAN LUN mapping error
Heap series_0x0A: 3 methods to solve the heap overflow problem at once
随机推荐
【科普】关于平板电脑的那些事
想通这点,治好 AI 打工人的精神内耗
领先实践|全球最大红酒App如何用设计冲刺创新vivino模式
【Web渗透】信息收集篇——Google搜索引擎(二)
开始记录自己的学习过程和目标
Codeforces Round # 806 (Div. 4) | | precipitation) bloodbath wudaokou
网络——TCP拥塞控制
良匠-手把手教你写NFT抢购软(一)
无需支付688苹果开发者账号,xcode13打包导出ipa,提供他人进行内测
Chapter 3: Use of GEE Data (3.4-3.11)
No need to pay for the 688 Apple developer account, xcode13 packaged and exported ipa, and provided others for internal testing
为什么四个字节的float表示的范围比八个字节的long要广
Heap series_0x0A: 3 methods to solve the heap overflow problem at once
初始C语言 C生万物
网络——数据交换方式
自定义过滤器和拦截器实现ThreadLocal线程封闭
Three ways to find prime numbers
4. Using Local Geospatial Data
Two ways to find the factorial of n
Heap series_0x09: Example of heap corruption (illegal access + uninitialized + heap handle mismatch)