MySQL为什么使用B+树索引

为什么数据库加了索引,查询就快了?

  • 没有索引,mysql查任何数据都需要全表扫描
  • 有了索引,就相当于书有了目录,可以减少查询范围
    • InnoDB使用的就是B+树

为什么哈希(hash)比树(tree)快,InnoDB还要选择B+树结构?

  • hash 例如hashMap 增删改查的时间复杂度为o(1)
  • 树 例如 B+树 增删改查的平均时间复杂度为o(lg(n))
  • 相对于单一查询,hash确实比树快
  • 但是对于 group by(分组) order by(排序) <,>(比较),hash 的时间复杂度变为o(n),而树的时间复杂度还未o(lg(n))
  • 根据实际出发,所以还是选择树

为什么选择B+树作为数据库的索引结构

第一种: 二叉树

MySQL为什么使用B+树索引
(1)当数据量大的时候,树的高度会比较高,数据量大的时候,查询会比较慢;
(2)每个节点只存储一个记录,可能导致一次查询有很多次磁盘IO;

第二种: B树

MySQL为什么使用B+树索引
(1)不再是二叉搜索,而是m叉搜索;
(2)叶子节点,非叶子节点,都存储数据;
(3)中序遍历,可以获得所有节点;

  • 每个节点布置只存储一个记录,而是一页记录(4K大小)
  • 磁盘读写并不是按需读取,而是按页预读,一次会读一页的数据,每次加载更多的数据,如果未来要读取的数据就在这一页中,可以避免未来的磁盘IO,提高效率;
  • 局部性原理:软件设计要尽量遵循“数据读取集中”与“使用到一个数据,大概率会使用其附近的数据”,这样磁盘预读能充分提高磁盘IO;
  • 中序遍历是什么意思? 查询1-5的数据
    ![在这里插入图片描述](https://img-blog.****img.cn/20191109153229923.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDg2OTAyMg==,size_16,color_FFFFFF,t_70 = 10*10)
第三种: B+树

MySQL为什么使用B+树索引

  • 非叶子节点不再存储数据,数据只存储在同一层的叶子节点上;
  • B+树中根到每一个节点的路径长度一样,而B树不是这样。
  • 叶子之间,增加了链表,获取所有节点,不再需要中序遍历;
  • 范围查找,定位min与max之后,中间叶子节点,就是结果集,不用中序回溯;
  • 叶子节点存储实际记录行,记录行相对比较紧密的存储,适合大数据量磁盘存储;非叶子节点存储记录的PK,用于查询加速,适合内存存储;
  • 非叶子节点,不存储实际记录,而只存储记录的KEY的话,那么在相同内存的情况下,B+树能够存储更多索引;

总结

  • 数据库索引用于加速查询
  • 虽然哈希索引是O(1),树索引是O(log(n)),但SQL有很多“有序”需求,故数据库使用树型索引
  • InnoDB不支持哈希索引
  • 数据预读的思路是:磁盘读写并不是按需读取,而是按页预读,一次会读一页的数据,每次加载更多的数据,以便未来减少磁盘IO
  • 局部性原理:软件设计要尽量遵循“数据读取集中”与“使用到一个数据,大概率会使用其附近的数据”,这样磁盘预读能充分提高磁盘IO
  • 数据库的索引最常用B+树:
    (1)很适合磁盘存储,能够充分利用局部性原理,磁盘预读;
    (2)很低的树高度,能够存储大量数据;
    (3)索引本身占用的内存很小;
    (4)能够很好的支持单点查询,范围查询,有序性查询;