MySQL 的索引,为什么是 B+而不是平衡二叉树

数据库为什么使用 B+ 树?

前言

讲到索引,第一反应肯定是能提高查询效率。例如书的目录,想要查找某一章节,会先从目录中定位。如果没有目录,那么就需要将所有内容都看一遍才能找到。

索引的设计对程序的性能至关重要,若索引太少,对查询性能受影响;而如果索引太多,则会影响增/改/删等的性能。

知识点

MySQL 中一般支持以下几种常见的索引:

  • B+树索引
  • 全文索引
  • 哈希索引

我们今天重点来讲下 B+树索引,以及为什么要用 B+树来作为索引的数据结构。

B+树索引并不能直接找到具体的行,只是找到被查找行所在的页,然后 DB 通过把整页读入内存,再在内存中查找。

1. 与二叉树相比

二叉树相比于顺序查找的确减少了查找次数,但是在最坏情况下,二叉树有可能退化为顺序查找。而且就二叉树本身来说,当数据库的数据量特别大时,其层数也将特别大。二叉树的高度一般是 log_2^n,B 树的高度是 log_t^((n+1)/2) + 1,其高度约比 B 树大 lgt 倍。n 是节点总数,t 是树的最小度数。

2. 与 B树相比

B 树在提高 IO 性能的同时,并没与解决元素遍历时效率低下的问题,正是为了解决这个问题,B+数应运而生。B+数只需遍历叶子节点即可实现整棵树的遍历,而 B 树必须使用中序遍历按序扫库,B+树支持范围查询非常方便。这才是数据库选用 B+树的主要原因。

另外,最后说一下,并不是说 B+树就比 B 树好,有很多基于频率的搜索是选用 B树,越频繁 query 的结点越往根上走,前提是需要对 query 做统计,而且要对 key做一些变化。

无论是 B 树还是 B+树由于前边几层反复 query,因此早已被加载入内存,不会出现读磁盘 IO。一般启动的时候,就会主动换入内存。在内存中 B+树并没有优势,只有在磁盘中 B+树的威力才能显现。

采用 B+ 树的索引结构优点:

B+树的高度一般为 2-4 层,所以查找记录时最多只需要 2-4 次 IO,相对二叉平衡树已经大
大降低了。
范围查找时,能通过叶子节点的指针获取数据。例如查找大于等于 3 的数据,当在叶子节点
中查到 3 时,通过 3 的尾指针便能获取所有数据,而不需要再像二叉树一样再获取到 3 的
父节点。

总结:

  • 1)二叉查找树(BST):解决了排序的基本问题,但是由于无法保证平衡,可能退化为链表

  • 2)平衡二叉树(AVⅥL):通过旋转解决了平衡的问题,但是旋转操作效率太低

  • 3)红黑树:通过舍弃严格的平衡和引入红黑节点,解决了 AⅥ旋转效率过低的问题,但是在磁盘等场景下,树仍然太高,IO 次数太多

  • 4)B 树:通过将二叉树改为多路平衡查找树,解决了树过高的问题

  • 5)B+树:在 B 树的基础上,将非叶节点改造为不存储数据的纯索引节点,进一步降低了树的高度;此外将叶节点使用指针连接成链表,范围查询更加高效。

你可能感兴趣的:(MySQL 的索引,为什么是 B+而不是平衡二叉树)