面试题:MySQL 的 3 层主键索引最多能支撑多少数据量?
我们知道MySQL InnoDB表的主键索引中,所有数据行都存储在B+树的叶子节点,内部节点只存储用于路由的主键值。
这是一个比较宽泛的题目,当被问到这类问题时,建议答题人缩小题目范围,如约定数据页大小、数据行大小和存储引擎类型等,再给估算。这样答题人既展示了计算能力,又体现了对存储结构的理解。
题目未说明MySQL使用的是哪种存储引擎,所以假设使用的存储引擎是常用的 InnoDB。三层主键索引结构 = 1层(根节点) + 1(中间层) + 1层(叶子节点)。
首先,查看MySQL一个数据页的大小:
sql
SHOW GLOBAL STATUS like 'innodb_page_size';
执行结果如下图所示,说明每个数据页占用存储空间的大小为16KB,这也是默认的大小,没有被调整:

然后,假设主键Id为bigint类型,那么主键长度就是8B,指针在Innodb源码中大小为6B,所以一共就是14B,再假设叶子节点存放的数据行占用的空间大小为1KB=1024B (能存很多内容了)。现在分析如何计算 3 层 B+Tree 总容量:
- 第一层是根节点,一个节点最多能存的指针个数是16KB / (8B + 6B) = 1170 (个);
- 第二层1170个节点,每个节点指向1170个叶子节点,故第三层叶子节点个数为1170 * 1170 个;
- 第三层是叶子节点,每个叶子节点能存的记录条数是:16k / 1k = 16 (个)。
最后,计算一张包含三层节点的InnoDB表最多可以存放的记录条数:
sql
1170 * 1170 * 16 = 21902400 ≈ 2千万
综上所述,一张使用B+Tree为索引结构的InnoDB表可以轻松容纳千万级数据行,而且树中节点的层数只需要3层。💡注意:实际数量会因数据页大小、索引字段长度、填充因子和数据行大小等因素有所浮动。一般来说,MySQL会把 B+Tree 根节点放在内存中,故查询时只需要两次磁盘I/O(第二层和第三层各1次)就可以找到目标记录。这也是为什么 MySQL 单表即使在千万级数据量场景下,通过合理使用索引,仍能实现亚秒级查询响应的原因之一!
下面介绍一下本文用到的计量单位。计算可以存储多少数据,就必须清楚计算机计量单位字节(Byte),它是基本的存储单位,常用大写字母 B 表示,是由8个bit( binary digit的缩写)组成的组合单位。即1 Byte = 8 bits,也可以写作1B = 8b。温馨提示,"字节是Byte"没错,但如果你看到小写的"b",那指的是比特(bit),比特是计算机中表示信息的最小单位,只能表示0或1的一种状态。
生活没有倒车档,世事没有后悔药。但愿这次分享的内容能与你产生共鸣,祝你今天技术判断更笃定,少踩坑、快进阶!🚀。认同的,别忘了关注点赞楼兰胡杨,提醒身边每一个正在寻求突破技术瓶颈的人。