为什么MySQL选择B+树做索引

目录

各种数据结构区别

Hash表作为索引

B树作为索引

B+树作为索引

为什么MySQL选择B+树做索引

Hash索引和B+树区别是什么?在设计索引是怎么抉择的?


各种数据结构区别

Hash表作为索引

  1. 使用hash表的目的是为了尽可能的散列,因此在使用hash表的时候要选择hash算法,避免hash碰撞和hash冲突
  2. hash表存储的数据是无序的,当需要进行范围查询的时候,只能挨个进行遍历对比,效率极低
  3. mysql中的memory存储引擎支持hash索引,innodb存储引擎支持自适应hash

B树作为索引

当b树作为索引时的结构:

那磁盘块1举例:16,34表示具体的key值,data表示行数据,p1,p2,p3表示实际的指针。

  如果需要读取28为key的这条数据时,读取顺序:

  1. 读取磁盘块1,拿16和34进行比较,发现在其中间,发现p2指针指向了磁盘块3
  2. 读取磁盘块3,拿25和31进行对比,发现在其中间,又发现p2指针执行了磁盘块8
  3. 读取磁盘块8,找到28对应数据,返回

     

B+树作为索引

B+树是在B树的基础上做的一种优化:

B+树每个节点可以包含更多的节点,这样做的原因有两个:

  1. 是可以降低树的高度,
  2. 是将数据范围变为多个区间,区间越多,数据检索越快。

  1. B+树的非叶子结点是没有数据的,所以同样大小的磁盘可以容纳更多的节点元素。这就意味着(B+树会更加矮胖,查询的IO次数会更少)
  2. B+树上所有的叶子结点形成有序双链表,便于范围查询
  3. 非叶子结点只存储key,叶子结点存储key和数据
  4. 叶子结点采用双链表进行连接,范围查询性能更高

为什么MySQL选择B+树做索引


1. B+树的磁盘读写代价更低:B+树非叶子节点上是不存储数据的,仅存储键值,而B树节点中不仅存储键值,也会存储数据。数据库中页的大小是固定的,innodb中页的默认大小是16KB。如果不存储数据,那么就会存储更多的键值,一次性读入内存的关键字也就越多,如此一来我们查找数据进行磁盘的IO次数会大大减少,数据查询的效率也会更快

2. B+树的查询效率更加稳定:B+Tree在树高度相同的情况下能够存储更多的索引数据,间接的减少了磁盘的I/O操作,B+Tree的I/O次数会更加稳定一些

3. B+树更便于遍历:由于B+树的数据都存储在叶子结点中,非叶子结点均为索引,方便扫库,只需要扫一遍叶子结点即可,但是B树因为其分支结点同样存储着数据,我们要找到具体的数据,需要进行一次中序遍历按序来扫,所以B+树更加适合在区间查询的情况,所以通常B+树用于数据库索引。

4. B+树更适合基于范围的查询:`B树在提高了IO性能的同时并没有解决元素遍历的我效率低下的问题,正是为了解决这个问题`,B+树应用而生。B+树只需要去遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作或者说效率太低。
 

MySQL中存储索引用到的数据结构是B+树,B+树的查询时间跟树的高度有关,是log(n),如果用hash存储,那么查询时间是O(1)。既然hash比B+树更快,为什么mysql用B+树来存储索引呢?

1. 从内存角度上说,数据库中的索引一般在磁盘上,数据量大的情况可能无法一次性装入内存,B+树的设计可以允许数据分批加载。
2. 从业务场景上说,如果只选择一个数据那确实是hash更快,但是数据库中经常会选中多条这时候由于B+树索引有序,并且又有链表相连,它的查询效率比hash就快很多了,hash还需要解决冲突。

Hash索引和B+树区别是什么?在设计索引是怎么抉择的?

  1. B+树可以进行范围查询,Hash索引不能。
  2. B+树支持联合索引的最左侧原则,Hash索引不支持。
  3. B+树支持order by排序,Hash索引不支持。
  4. Hash索引在等值查询上比B+树效率更高。
  5. B+树使用like进行模糊查询的时候,like后面(比如%开头)的话可以起到优化的作用,Hash索引根本无法进行模糊查询。

mysql为什么要使用B+树作为索引

你可能感兴趣的:(面试题,Java,b树,面试)