MySQL之B树和B+树

首先抛个问题,MySQL的索引为何用树而不是其他数据结构如hash,hash的读和写都是O(1),而树的话查询和插入都是O(log(n))?
答:因为索引设计成树,是和SQL需求相关的,如果单独只查询某条数据,自然是hash算法快,但是我们平常用的查询往往不是只查询单条数据,而是order by,group by,< >这种排序查询,遇到这种情况,hash就会退化成O(n),而树因为它的有序性依然保持O(log(n))高效率。还有一个点是,如果索引的值有重复的话,会发生hash碰撞,导致查询效率降低。
那为何用的是B+树呢?这就得比较B树,B+树与红黑树的区别了。

1.B+树的非叶子节点只保存索引,不保存行记录。而B树叶子节点和非叶子节点都存储索引和行记录,这样的话,同样的空间,B+树能存储更多的索引。这就意味着同样的数据,B+树比B树更”矮胖“,减少IO次数。
2.查询的时候,由于B树叶子节点和非叶子节点都存在行记录,也就是是说,B树查询其实是不稳定的(好的时候,只查根节点,坏的时候,查到叶子节点)。而B+树查询最终必须到叶子节点,查询销量稳定。
3.B树范围查询只能通过中序遍历查询来定位最小和最大值,而B+树通过链表就能实现,查询更方便。
综合起来:B+树比B树优势有三个:1.IO次数更少;2.查询性能更稳定;3.范围查询简便。
参考:https://blog.csdn.net/qq_26222859/article/details/80631121

InnoDB一棵B+树可以存放多少行数据?这个问题的简单回答是:约2千万
那如何计算呢?首先我假设每行记录为1k,
首先假设树高为2,那么根节点存储的指针对应每个叶子节点。也就是说,最大的话,有多少个指针就有多少个叶子节点。
这棵B+树存储的总行数=根节点指针树*每个叶子节点的行记录树
那么根节点能存储多少指针呢?
InnoDB最小单位为页,一页为16k,我们假设主键ID为bigint类型,长度为8字节,而指针大小在InnoDB源码中设置为6字节,这样一共14字节,那么一页的总指针树为16k/(8+6) = 1170。
每个指针对应1页,假设每行记录为1k(实际上现在很多互联网业务数据记录大小通常就是1K左右),那么一页大概能存16条行记录。
所以这棵B+树总行数为:117016 = 18720
三层的话,总指针数为1170
1170,故总行数为1170* 1170*16=21902400
所以当单表数据超过千万级别后,就得考虑分表了,否则B+树的层级可能会超过3级,造成查询效率下降。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章