mysql索引知识记录
1.b树和b+树的区别是什么
b+树是b树的增强类型


2.Innodb中的b+树有什么特点
叶子结点之间是双向链表
3.什么是innodb中的page
默认16kb,多条行记录放在一个page内,索引记录也是放在page内。所以page大小限制着一次IO获取数据条数,同样也限制单个page索引块能存放多少记录,控制b+树的层高。最下面附上,如何计算三层的最大容量
4.innodb中的b+树是怎么产生的
由图可知,mysql的主键最好是递增的,不然新增还要修改之前page

5.什么是聚簇索引
叶子结点保存全部数据,与之对应的是普通索引叶子结点保存主键,需要回表;图中最下层应该是双向链表;这棵主键树从上到下往往代表着走索引,不过索引树从左往右也是在走索引,因为索引树的叶子结点数据更少

6.innodb是怎么支持支持范围查找能走索引的
a是索引,那么a>2,可以先走索引a匹配到a=2再通过双向链表往后查找;小于还有in、between and都是一个道理,不过这里mysql会根据select的数据字段,数据规模等;决定是要走a索引再回表,还是直接扫全表,这一点需要好好体会
7.什么是联合索引
b,c,d联合索引,索引结构如下

8.什么是最左匹配原则
索引匹配,本质就是排序,cd没有办法比较,但是b**,bd这都是可以比较,走到部分索引的,同样这里也要判断的,因为这是要回表
9.为什么要遵守最左匹配原则才能利用到索引
同上面一个问题,因为能比较才能排序
10.什么是索引条件下推
一个优化策略,bd索引匹配到多条记录时,可以先对bd条件在索引叶子结点上判断,再回表;而不是先回表再判断
11.什么是覆盖索引
select b where b>1;只需要b字段,不用回表了,同理多一个a主键也不用回表;这里,没有where,selct b也能走索引;还有selct c虽然不符合最左匹配,但是bcd索引的叶子结点,一个page能存放更多的数据,比扫描全表要好,也会走索引
12.有哪些情况索引失效
使用字段值类型不相符的条件查询,涉及到数据的隐式转换;selct b order by b,c,d 回表的消耗远远大于排序;a+1=1这样的条件,涉及到操作字段的也不走
计算三层最大容量
要计算 MySQL 中三层 B + 树能存储的最大数据量,需从B + 树的存储结构原理入手,核心是先计算每个节点(根节点、叶子节点)能容纳的 “索引项数量”,再通过层级关系推导总数据量。以下是详细计算过程:
一、关键前提与基础概念
首先明确题目给定条件和 MySQL B + 树的核心特性:
数据行大小:1KB(即叶子节点中 “数据记录” 的单条大小);
主键类型:BIGINT,占8 字节(无符号为 8 字节,有符号也为 8 字节,不影响计算);
B + 树结构规则:
非叶子节点(根节点、中间层节点):仅存储 “索引项”(主键 + 子节点指针),不存实际数据;
叶子节点:存储 “索引项 + 实际数据”(或主键 + 数据行指针,InnoDB 中主键索引叶子节点直接存数据,即 “聚簇索引”,此处按聚簇索引计算,更贴合实际);
节点大小:MySQL 默认页大小为16KB(innodb_page_size默认值,非叶子节点和叶子节点均占用 1 个页,这是计算的核心基准);
指针大小:InnoDB 中指针占6 字节(指向子节点的页地址,固定长度)。
二、分步计算各层节点容量
- 第一步:计算非叶子节点(根节点、中间层)的索引项数量
非叶子节点的每个 “索引项” 由 主键(8 字节)+ 子节点指针(6 字节) 组成,单个索引项总大小为:
8字节(BIGINT主键) + 6字节(子节点指针) = 14字节
非叶子节点的容量为 16KB(16384 字节),因此每个非叶子节点能容纳的最大索引项数量为:
节点总大小 ÷ 单个索引项大小 = 16384字节 ÷ 14字节 ≈ 1170(向下取整,因不能存储半个索引项)。
即:每个非叶子节点最多能指向 1170 个子节点(索引项数量 = 子节点数量)。
2. 第二步:计算叶子节点的数据记录数量
叶子节点存储 “主键(8 字节)+ 实际数据行(1KB)”,单个叶子节点项的总大小为:
8字节(主键) + 1024字节(数据行) = 1032字节
叶子节点同样占用 16KB(16384 字节),因此每个叶子节点能容纳的最大数据记录数量为:
节点总大小 ÷ 单个叶子节点项大小 = 16384字节 ÷ 1032字节 ≈ 15(向下取整,1032×15=15480 字节 ≤16384,1032×16=16512 字节>16384)。
即:每个叶子节点最多存储 15 条数据记录。
三、计算三层 B + 树的总数据量
B + 树的 “层数” 指从根节点到叶子节点的深度,三层 B + 树的结构为:
根节点(1层) → 中间层节点(2层) → 叶子节点(3层)
- 中间层节点总数
根节点最多指向 1170 个子节点,因此中间层节点总数 = 根节点索引项数量 = 1170 个。 - 叶子节点总数
每个中间层节点最多指向 1170 个子节点(叶子节点),因此叶子节点总数 = 中间层节点数 × 单个中间层索引项数量 = 1170 × 1170 = 1368900个。 - 总数据记录数
每个叶子节点最多存储 15 条数据,因此总数据量 = 叶子节点总数 × 单个叶子节点记录数 = 1368900 × 15 = 20533500条(约 2053 万条)。
四、关键说明(影响实际容量的因素)
页大小差异:若innodb_page_size不是 16KB(如 8KB、32KB),计算结果会变化(如 32KB 页会提升节点容量);
数据行碎片:实际存储中数据行可能存在碎片(如删除后空闲空间),导致叶子节点实际存储量低于理论值;
索引类型:若为 “非聚簇索引”(如二级索引),叶子节点存储 “主键 + 二级索引值”,需重新计算叶子节点容量,但三层 B + 树的层级逻辑一致;
指针大小:不同 MySQL 版本或存储引擎的指针大小可能微调(如个别场景为 4 字节),但对百万级别的总容量影响较小。
最终结论
在 “1KB 数据行、BIGINT 主键、16KB 页” 的前提下,MySQL 三层 B + 树最大可存储约 2053 万条数据。

浙公网安备 33010602011771号