MySQL 单表大数据量下的 B-tree 高度问题
内容提要
MySQL中单表行数不会影响B树的高度,大表也不会超过4层。即使是单行1KB的表,数据在10TB以内,B树高度也在4层以内,可以存138亿行。MySQL不用担心数据量大时B树高度增加影响性能的问题。
延伸解读
B-tree 高度为何不随数据量线性增长
B-tree 是一种多路平衡查找树,每个节点(页)可以存储大量键值。在 InnoDB 中,非叶子页存储索引键和子页指针,叶子页存储实际记录。由于每页可容纳数百至上千个条目,树的分支因子很高,因此树高增长极慢。即使数据量达到数十 TB,树高也仅从 3 层增至 4 层,而非线性增长。这解释了为何大表不会因 B-tree 高度增加而显著影响查询性能。
主键类型对 B-tree 容量的实际影响
文章对比了 INT 和 BIGINT 主键的 sysbench 表。INT 主键下,4 层 B-tree 可存约 1480 亿行、27.9TB 数据;改为 BIGINT 后,由于非叶子页可存储的键值数减少,4 层仅能存约 680 亿行、12.8TB 数据。可见主键长度会明显影响 B-tree 的容量,但即便如此,BIGINT 主键下 4 层仍能支撑数十亿行,远超市面上多数单表规模。
复杂表结构下的 B-tree 高度验证
文章以 Polarbench 的 SaaS 日志表为例,该表包含多个变长字段,单行约 974 字节。计算显示,叶子页仅能存约 16 条记录,但非叶子页仍可存 952 个条目。因此 4 层 B-tree 仍可容纳约 138 亿行、12.8TB 数据。这说明即使表结构复杂、单行较大,B-tree 高度也不会超过 4 层,进一步验证了 MySQL 处理大表的能力。
对分库分表策略的再思考
过去流传的“单表不要超过 500 万行”的说法,源于对 B-tree 高度增长的担忧。但根据文章分析,10TB 以内 B-tree 高度不超过 4 层,超过 10TB 也仅到 5 层,而 MySQL 单表最大支持 64TB。因此,仅因数据量大而进行分库分表可能并非必要,除非有其他业务或运维需求。PolarDB 线上已有 43TB 的大表实例,进一步说明大表在技术上是可行的。
Q&A
MySQL中单表的B树高度会受到行数影响吗?
不会,MySQL中单表行数不会影响B树的高度,大表也不会超过4层。
在MySQL中,B树的高度最多可以达到多少层?
在MySQL中,B树的高度最多可以达到5层,通常在10TB以内的数据情况下,B树高度保持在4层。
如果MySQL表的数据量超过10TB,会有什么影响?
即使数据量超过10TB,B树的高度仍然不会超过5层,因此不会影响性能。
MySQL的单表最大容量是多少?
MySQL支持的单表最大容量为64TB。
在InnoDB中,B树是由哪些部分组成的?
在InnoDB中,B树主要由叶子页和非叶子页组成,叶子页存储记录,非叶子页存储索引信息。
DBA们对MySQL表大后B树高度增加的担忧是否有依据?
DBA们的担忧并没有依据,实际情况是B树高度不会因为表大而增加,性能不会受到影响。