怎么知道实际生产环境的B树索引有多少层

Q:在实际生产环境中,InnoDB中一棵B+树索引一般有多少层?可以存放多少行数据?

关于这个问题最近好像在牛客上经常看到,感觉没啥意义,可能主要考察的是对B+索引的理解吧。先上答案:

A:一般是2~3层,可以存放约两千万行的数据。

前文说过,页是InnoDB磁盘管理的最小单位,在InnoDB存储引擎中,默认每个页的大小为16KB。而页里面存放的东西就是一行一行的记录。

假设一行数据的大小是1k,那么一页就可以存放16行这样的数据。

众所周知,B+树的叶子节点存储真正的记录,而非叶子节点的存在是为了更快速的找到对应记录所在的叶子节点,所以可以简单理解为非叶子节点存放的是键值+指针。这里用指针来描其实述不是太准确,准确来说是页的偏移量,不过指针更好理解~

通过索引组织表的方式,数据行被存放在不同的页中。如下图所示:

假设我们要从上图这棵B+树种找到主键是20这行数据select*fromtablewhereid=20;

首先找到B+树的根节点,即存储的非叶子节点的页page_number=10,在该页上通过二分查找法以及指针定位到id=20这行数据存在于page_number=12这页上,然后同样的在这页上用二分查找即可快速定位id=20这行记录。

说这些和文题不是很相关的话题,其实就是想要大家知道:页作为InnoDB磁盘管理的最小单位,不仅可以用来存放具体的行数据,还可以存放键值和指针。

回到文题,我们先从简单的入手,假设B+树只有两层,即一个根节点和若干个叶子节点,如下图:

那么对于这棵B+树能够存放多少行数据,其实问的就是这棵B+树的非叶子节点中存放的数据量,可以通过下面这个简单的公式来计算:

根节点指针数*每个叶子节点存放的行记录数

每个叶子节点存放的行记录数就是每页存放的记录数,由于各个数据表中的字段数量都不一样,这里我们就不深究叶子节点的存储结构了,简单按照一行记录的数据大小为1k来算的话(实际上现在很多互联网业务数据记录大小通常就是1K左右),一页或者说一个叶子节点可以存放16行这样的数据。

那么B+数的根节点(非叶子节点)能够存储多少数据呢?

非叶子节点里面存的是主键值+指针,我们假设主键的类型是BigInt,长度为8字节,而指针大小在InnoDB中设置为6字节,这样一共14字节。

为了方便行文,这里我们把一个主键值+一个指针成为一个单元,这样的话,一页或者说一个非叶子节点能够存放/14=个这样的单元。

也就是说一个非叶子节点中能够存放个指针,即对应个叶子节点,所以对于这样一个高度为2得B+树,能存放(一个非叶子节点中的指针数)*16(一个叶子节点中的行数)=行数据。

当然,这样分析其实不是很严谨,按照《MySQL技术内幕:InnoDB存储引擎》中的定义,InnoDB数据页结构包含如下几个部分:

想要深究的小伙伴可以去看书中的4.4章节,这里我就不再多分析了。

OK,分析完高度为2的B+树,同样的道理,我们来看高度为3的:

根页(page10)可以存放个指针,然后第二层的每个页(page:11,12,13)也都分别可以存放个指针。这样一共可以存放*个指针,即对应的有*个非叶子节点,所以一共可以存放**16=行记录。




转载请注明:http://www.aierlanlan.com/rzfs/7198.html