本文共 1538 字,大约阅读时间需要 5 分钟。
更多介绍,可前往查看
通过之前的介绍,可知,B+ Tree在存储大数据量上完全没有问题,可以满足需求。
B+Tree 还有个特性:叶子节点之间有指针相连
B-Tree的叶子结点是独立的,没有没有任何连接:从上面两张图可以很明确的看出:
在B-Tree中,每个节点元素绝对是不会冗余的,在整个树里面是唯一的。 在B+ Tree中,会把处于中间的节点元素都提上去了(为了高效查找),除此之外,B- Tree 比 B Tree还多了指针。 上图是最原生的B+Tree,真正MySQL底层的B+ Tree如下图,顶层对B+ Tree做了优化: 它的指针是双向的,如果是末尾节点的话,后面还有一个指针是指向第一个节点同时第一个节点也指向最后一个节点,有点类似双向链表。那么在叶子节点增加了连接的指针有什么用呢???
答:在回答这个问题之前,先来介绍下MySQL索引的另外一种实现方式。我们平时在建索引的时候,会看到索引方式这里有两种方式,一种是上面说的B+ Tree,另一种是Hash表的方式。比如有以下数据:
现查询SQL:select * from t where t.data1 = 6; 将data1列表作为索引且将索引方式设置为Hash。底层查找过程大致如下:
拿到这条SQL语句,发现索引是Hash索引,MySQL会先把索引的结果值做一次Hash运算(比如:hash(6))得到一个结果值,根据这个结果值可以很快从Hash表中找到数据行对应的磁盘文件地址指针。 因为在Hash表中存储着Hash值和数据行对应的磁盘文件地址指针的映射关系,MySQL底层有自己的Hash散列算法,Hash表这种结构性能是非常高的,不论表数据有多少行,不论查询哪一条数据,只要条件走的是Hash索引,都能通过hash算法得到结果值之后快速从Hash表中定位到数据的磁盘指针。从上述描述我们发现:Hash索引,才是真正的高性能。B+ Tree至少还要做几次磁盘IO,但是Hash索引不管数据量有多大,只要经过一次Hash算法,而Hash算法是非常快的,算到结果后去Hash表中可以快速定位到磁盘地址指针。它的性能和数据量不是成正比的。
那么实际上,工作中使用的所以99%都是B+ Tree,很少使用Hash索引,为什么呢??? 主要是因为Hash索引不支持范围查询。 比如上述的SQL改为:select * from t where t.data1 < 6; 那么这个时候Hash索引就做不到了。范围查找是我们工作中经常遇到的业务场景,不能因为性能高就不能让大多数业务场景无法满足。Hash索引的使用场景:如果数据库99%以上的场景都只要等值查询,那么就可以使用Hash索引,性能比较高
那么我们现在回到第一大点最后的那个疑问,B+ Tree 叶子节点增加了连接的指针有什么用呢???
为了提高范围查找的性能。 比如查找大于20的数据。 如果没有指针:会经过1、2次磁盘IO定位到20这个节点,会先把当前查到的节点中的数据加载到结果集中,然后就又要回到根节点,再次查询,把下一个节点中的数据加载到结果集中,然后再回到根节点重复之前的操作,后面有所有的节点都要回到根节点去再次查询,然后后加数据加载到结果集中。 加了指针之后:B+ Tree的叶子节点是从左往右依次递增的,每个小节点都满足二叉树的特性。现在每个节点都有一个小小的存储空间存储了下个节点磁盘文件地址的指针。经过1、2次磁盘IO定位到20这个节点,先把当前节点的数据加载到结果集中,然后根据指针顺藤摸瓜,把后面的数据全部加载到结果集中,相比没有指针性能大大提升了。转载地址:http://zoyai.baihongyu.com/