云计算、AI、云原生、大数据等一站式技术学习平台

网站首页 > 教程文章 正文

从B+树的角度分析为什么单表2000万要考虑分表?

jxf315 2025-03-07 20:02:30 教程文章 28 ℃

前言:

我们知道数据库单表数据量达到一定数量之后,要考虑分库分表进行存储数据,为什么要考虑分库分表,达到多少量进行分库分表?下面我们从B+树的角度分析下。

多少数据分析

理论上来说,只要磁盘空间够,存多少都可以,但是随着数据量的增多,查询效率会下降的,根据实际经验来说,单表抗2000万数据量,通过索引查询问题不大,那么这个数字确实是一个经验值,但是他背后是不是有一定的计算逻辑呢?如何计算出这个数据的呢?

首先我们需要知道的事,单表能存数据不用考虑分库分表,这要看记录大小、存储引擎设置、硬件配置等多种因素。那么如果一定要做数据计算,我们可以从B+树存储的角度来分析一波。

B+树的高度限制

B+树是InnoDB存储引擎使用的索引结构,我们都知道,随着表中数据量的增加,B+树的高度会逐渐增加。如果B+树的高度过高,每次查询需要经过较多的层级,会导致查询性能下降。因此,B+树的高度限制是单表存储量的个瓶颈。对于B+树的高度限制,一般建议将B+树的高度控制在3到4层以内,以获得更快的查询性能。

数据页

我们都知道,Innodb中的数据页默认大小是16KB,并且B+树的每个节点都对应着一个数据页,包括根节点、非叶子节点和叶子节点。B+树的非叶子节点对应着数据页,其中存储着主键+指向子节点(即其他数据页)的指针。B+树的叶子节点包含实际的数据行,每个数据行存储在一个数据页中。

估算

有了以上的背景之后,我们就可以基于B+树的高度及结构,还有数据页的大小,来估算单表的数据量了。

我们都知道,B+树的叶子节点和非叶子节点存储的内容是不一样的。所以需要区分开来进行计算。

我们很容易知道以下公式:

能存多少条记录=叶子节点的数量*每个叶子节点中能存的数量。

叶子节点的数量=根节点之下的第一层非叶子节点的数量^(树高度-1)

最终我们只需要计算出非叶子节点的数量、叶子节点中能存的数量、树高度就行了。

非叶子节点数量

个根节点中,可以扩展出多少个子节点?

已知一个根节点的存储量是16KB,并且他作为非叶子节点,他只需要存储一个主键+一个指针就行了。假设是一个bigint类型的主键(8字节),和默认6字节的指针。那么可以存储:

16*1024/(8+6)≈1170

根节点可以扩展出1170个二层高度的子节点,而三层的B+树则会有两层非叶子节点。那么最终就能关联出 1170*1170=1,368,900个叶子节点。

叶子节点的存储行数

已知一个叶子节点有16KB,那么它能存储多少数据量就取决于单行数据的大小了。假设单行数据量1KB,那么他就能存储16条,假设单条数据量500B那么他就能存储32条。

估算结果

基于以上计算方式,假设单条数据的存储空间是1KB,那么3层高度的B+树最终的可存储数据量为:

1170*1170*16=21,902,400,即2000万。

总结

以上具体计算分析了单表数据量达到多少,我们要进行分库分表的操作,在这个数据量范围内我们可以不用分库分表,毕竟分库分表会增加系统的复杂性。

最近发表
标签列表