• 进入"运维那点事"后,希望您第一件事就是阅读“关于”栏目,仔细阅读“关于Ctrl+c问题”,不希望误会!

查看InnoDB表每个索引的高度?

MySQL InnoDB 彭东稳 6年前 (2018-08-01) 28915次浏览 已收录 0个评论

我们知道InnoDB表是索引组织表,分为聚集索引和二级索引,但不管哪种索引,其结构都是B+树结构。由于InnoDB B+树结构高扇区特性,所以每个索引高度基本在3-4层之间,如果数据量比较大,页比较小,如4K,那么高度也是可能破4的。问题来了,以上说法都是我们根据理论知识计算得出的结果,那么在InnoDB中如何查看每个索引的高度呢?InnoDB也没有提供相应的视图进行查看。然,只要明白InnoDB索引的内部构造,就能迅速得出索引的高度。

姜总这篇文章给出了一个方法,如下图InnoDB索引的内部构造:

查看InnoDB表每个索引的高度?

InnoDB是索引组织表,每个页都包含一个PAGE_LEVEL的信息(见上图右半部分),用于表示当前页所在索引中的高度。默认叶子节点的高度为0,那么root页的PAGE_LEVEL + 1就是这棵索引的高度。接下去的问题就是怎样得到一张表所有索引的Root页所在的位置呢?其实InnoDB中Root页默认就在3号页,且Root页的位置通常是不会更改的,为什么是3号页呢?因为0,1,2号的Page被类型为“FSP_HDR”、“IBUF_BITMAP”、“INODE”分别占用了,从3号Page开始才是存放数据和索引的页(Index)。

其实官方提供了内部视图来查看每个索引的Root页,通过下面的SQL语句可以查出某这表对应索引的Root页:

运行上述的SQL语句应该可以得到类似如下的结果(space等于0的为系统表):

其中(SPACE,PAGE_NO)就是索引的Root页。SPACE对应每个表空间ID号,PAGE_NO对应每个页的ID号。

有了这些信息就可以方便的定位啦,因为PAGE_LEVEL在每个页的偏移量64位置初,占用两个字节,通过hexdump这样的工具就可以快速定位到所需要的树高度信息:

查看sbtest1表,49216表示的是3*16384+64(这里innodb_page_size设置为了16384,如果是8192就是3*8192),即第3个页偏移量64位置开始读取2个字节,这里PAGE_LEVEL为00 02,那么索引的高度就为3。

最后,如果我们不知道索引内部结构,那么就可以使用工具来协助,innodb_ruby是一个非常好的各种维度查看索引及页结构的工具。所以,同样使用innodb_ruby查出每个表的索引信息。

id:表示此索引的ID。

name:索引的名称,PRIMARY代表的就是聚集索引,因为InnoDB表是聚集索引组织表,行记录就是聚集索引;idx_c就是辅助索引的名称。

root:索引中根节点的page号,可以看出聚集索引的Root节点是第3号page(前0、1、2号Page已经被使用),辅助索引的根节点是第4个page。

fseg:page的说明,internal表示非叶子节点或属于根节点,leaf表示叶子节点(也就是数据页)。

used:索引使用了多少个page,可以看出聚集索引的非叶子节点使用了36个page,叶子节点使用了41094个page;辅助索引的非叶子节点使用了521个页,叶子节点使用了36159个page。

allocated:索引分配了多少个page,可以看出聚集索引的非叶子节点分配了96个page,叶子节点分配了41120个page;辅助索引的非叶子节点分配了608个页,叶子节点分配了41376个page。

fill_factor:索引的填充度,used/allocated表示填充度,也就是实际使用的大小百分比。

同样,现在我们知道了Root节点页后,就可以使用innodb_ruby的另外一个功能,打印页结构信息,需要了解InnoDB页结构。

页结构信息中有一个level字段,表示的就是Root节点页的高度,同样,level + 1就等于这个索引的高度。


如果您觉得本站对你有帮助,那么可以支付宝扫码捐助以帮助本站更好地发展,在此谢过。
喜欢 (0)
[资助本站您就扫码 谢谢]
分享 (0)

您必须 登录 才能发表评论!