又到了每周跟小伙伴吹牛的时间了,作为一个小菜鸟,每天都有很多学习的东西,今天要给小伙伴们分享之前看到的一篇文章,MySQL的单表存储,为什么建议在千万级别?
1、B树和B+树的区别
B树和B+树,都是一种平衡树(不是平衡二叉树,而是一种平衡多路查找树)。B树也称之为B-树(B-tree),B树的每一个节点至多包含k个子节点,k也就是B树的阶数,阶数由磁盘页的大小决定。
B树是一种自平衡树,新增节点和删除节点后,都会按照规则进行平衡,已满足B树的规则。可以看一下这篇文章,有图有真像,可以把枯燥的东西,画出来,很有意思 www.jianshu.com/p/8b653423c…
B+树,跟B树,原理和存储的结构都是一样的,只是B+树的非叶子节点,是不存储数据的,仅仅只是存储叶子节点的索引,所有的数据都存放在叶子节点上面。这样有什么好处呢?主要有以下这么节点:
B+树具有更好的磁盘读取能力,具有更好的IO性能
B+树的所有的数据都是存放在叶子节点上面,非叶子节点只是存放索引的数据和指针,因此相比较B树每个节点都存放数据,存放索引指针明显可以存储更多的索引,因此在磁盘页大小相同的情况下,B+树的每一个非叶子节点可以存放更多的索引,也可以更快的找到需要查找的数据。
B+树的查询效率更稳健
B+树的所有的数据,都存放在叶子节点上面,无论查询任何数据,都需要最终落到叶子节点上面,相比较B树数据落在每一个节点上面,B+树的性能更加稳定,也更加稳健,可能在某些场景下面,不如B树性能高,但是大量数据样本来说,B+树的性能要比B树更加稳定。
B+树具有更好的全表搜索能力
B+树的所有的数据,都存放在叶子节点上面,进行全表扫描时,只需要扫描所有的叶子节点即可,B树的数据也会存放在非叶子节点上面,全表扫描时,需要扫描整个树。
2、B+树的优点
B+树的优点,上面也有提及,主要就是每个非叶子节点里面,只是存储索引数据,因此可以存储更多索引,降低树的高度,减少IO的次数。
3、为什么B+树索引在千万级别的时,效率比较高
首先了解一个概念:
页:innodb是以页为单位进行存储和数据交换,每一页的大小为16K
指针:mysql的指针大小一般是6个字节
如上图所示:这是一个innodb的B+树索引(很有可能不满足B+树索引的节点要求,但是肯定是能表达出意思哈),B+树的非叶子节点,只是存放索引和指针,叶子节点,才会真正的存放实际的数据。
我们假设一个B+树的高度为2,mysql的每个索引大小为8个字节,指针大小为6个字节,一行记录的数据大小为1K。
可以存储的数据数量 = 根节点指针数*单个叶子节点记录行数。
一棵高度为2的B+树,指针的个数为16K/14字节,大约1170个,每一页16K可以存放16行记录,那么最终也就可以存放1170*16 = 18720
如果按照这个理论扩充到高度为3的B+树,则可以存储1170 * 1170 * 16 =21902400 条记录,
如果扩展到4层,则变成1170 * 1170 * 1170 * 16 ,大约是2.5亿个数据左右
当高度为3时,每个数据的检索次数为3次,只需要最多3次磁盘调度就可以拿到自己想要的数据。虽然高度为3和高度为4的B+树,仅仅是高度加了1,但是存储的数据缺失扩大了1000多倍,考虑到检索的效率和磁盘IO等多方面的性能,mysql在千万级别时,性能更好。
4、一些思考
索引的大小会影响每一个节点存放指针的数量,如果一个索引非常大,那么指针的数量就会变少,B+树的高度,就有可能会高,这样势必会影响查询的效率和IO的效率。因此很多资料或者规范上面,建议Mysql的索引长度不要设置太长,同时建议使用定长的索引和数字索引,尽量不要使用varchar等作为主键索引,原因应该也是会影响指针的数量和大小的比较效率问题。
5、结束语
感觉小伙伴们,能够看完这边文章,能够获得小伙伴的支持,将是我最大的动力,也是继续学习前进的最大动力