经常网上看到有人说500w或两千万就应该考虑分表,我自己是没有好好想过为什么,稍研究了一下。
其实, 如果了解B+树数据结构,我们自己就可以计算和预判数据量达到多少后数据库性能可能会下降,并且按业务现有的数据评估要不要分表。
首先复习一下B+树。一个主键索引的B+树数据结构大概长这样:

如所见,这些大框(不是有数字的小框)都我们称之为节点或“页”,每页大小在mysql默认为16kb(官方说这是mysql做了大量的实验和调优后得出来的合适值)。请看第一页,假设索引的类型用的是bingint类型,那么"50"这一格大小为8byte,"50"隔壁的格存储的是"50"到"70"之间的数据页的地址,mysql给这个地址大小为6byte。
所以一个页可以存储:
16kb/(8byte+6byte)=1170(个bigint)
假设一行记录占1kb,在三层b+聚簇索引树中我们可以存 1170 * 1170 * (16kb/1kb) = 21902400(条记录)
很多建议两千多万分表这个说法来自于这里
然而,不是每一张业务表的记录大小都等于1kb,1kb空间足以让线上大多数业务的一条数据撑死。
比如有这么一条记录,字段及类型长这样:
| 字段 | id | name | age | gender |
|---|---|---|---|---|
| 类型 | bigint | char(20) | int | tinyint |
| 占用空间 | 8byte | 21byte | 4byte | 1byte |
这条记录的大小粗略的等于34个字节,那么这个表的三层B+树能存 1170 * 1170 * (16kb/34byte) = 659809800(条记录)
就这个表而言,可以认为数据增长到6.59亿条之前都不太会有性能上的问题。
因此在业务中面对那么多天马星空的表结构、索引的情况、单条数据平均大小,并不应该死认500w或者2000w,因为阿里开发手册上的建议是来自于阿里自己的数据,跟我们的未必一样哦。
欢迎评论区battle, 最后祝大家工作顺利生活愉快!
posted on
浙公网安备 33010602011771号