假设每条 SQL 是 1kb,主键 id 是 bigint 类型,一棵高度为 4 的 b+树能存储多少数据。
在 innodb 存储引擎里面, 最小的存储单元是页(page),一个页的大小是 16KB。
查看页的大小语句:
这就说明了一个页的大小为 16384B, 也就是 16kb。
show variables like 'innodb_page_size';
#innodb_page_size 16384
一个页的大小为 16kb 假设一行数据的大小是 1kb,那么一个页可以存放 16 行这样的数据.那如果想查找某个页里面的一个数据的话,得首先找到他所在的页.innodb 存储引擎使用 B+树的结构来存储数据。如果是在主键上建立的索引就是聚簇索引,即只有在叶子节点才存储行数据,而非叶子节点里面的内容其实是键值和指向数据页的指针
。
因此,我们首先解决一个简单一点的问题:如果是 2 层的 B+树,最多可以存储多少行数据?如果是 2 层的 B+树,即存在一个根节点和若干个叶子节点,那么这棵 B+树的存放总记录数为:根节点指针数单个叶子节点记录行数。因为单个页的大小为 16kb,而一行数据的大小为 1kb,也就是说一页可以存放 16 行数据。然后因为非叶子节点的结构是:“页指针+键值”
,我们假设主键 ID 为 bigint 类型,长度为 8 字节(byte),而指针大小在 InnoDB 源码中设置为 6 字节(byte),这样一共 14 字节(byte),因为一个页可以存放 16k 个 byte,所以一个页可以存放的指针个数为 16384/14=1170 个。因此一个两层的 B+树可以存放的数据行的个数为:
一页可以存放1170个指针,一页可以存放16行的数据,1170x16=18720(行)
那么对于高度为 3 的 B+树呢?也就是说第一层的页,即根页可以存放 1170 个指针,然后第二层的每个页也可以存放 1170 个指针。这样一共可以存放 1170x1170 个指针,所以一共可以存放 1170x1170x16=21902400(2 千万左右)行记录。也就是说一个三层的 B+树就可以存放千万级别的数据了。
而每经过一个节点都需要 IO 一次,把这个页数据从磁盘读取到缓存,也就是说读取一个数据只需要三次 IO。
继续来说,高度为 4 的 B+树呢?1170x1170x1170x16 约等于 200 亿。