MySQL索引数据结构

前言

MySQL中表里面的数据越来越大的时候,查询数据就会变慢,为了解决查询变慢的问题常用的办法是在表上建索引,然后根据索引查询数据就会更快。

MySQL中,用的最多的是InnoDB存储引擎,InnoDB中的索引采用B+Tree这种数据结构。B+Tree 索引是 B+Tree 在数据库的一种实现。B+Tree 中的B代表平衡(balance),而不是二叉(binary),因为 B+Tree 是从 “平衡二叉树” 再经过 “B树(B-Tree)” 一步步演化而来的。

其实最终选用 B+树 是经历了漫长的演化:

二叉排序树 → 二叉平衡树 → B-Tree(B树) → B+Tree(B+树)
现在我们详细聊聊B+Tree索引的前世今生

索引结构

哈希索引

对于哈希索引来说,底层的数据结构就是哈希表,因此在绝大多数需求为单条记录查询的时候,可以选择哈希索引,查询性能最快;
有个好处,新增会很快,只需要往后追加;但也有缺点,
因为不是有序的,所以哈希索引做区间查询的速度是很慢的。

所以,哈希表这种结构适用于只有等值查询的场景,比如 Memcached 及其他一些 NoSQL 引擎。

二叉树

二叉树,分2个叉的树,左子树的键值 < 根的键值 < 右子树的键值,且节点中存储了键(key)和数据(data),二叉树数据分布不均匀的时候会退化成链表。

二叉树的特点:

二叉树的平均时间复杂度为 O(log(N))
每个节点最多只能有两个子节点

数据库中的数据基本都是放在磁盘中的,每读取一个二叉树的结点就是一次磁盘IO。

  • 数据分布很好的情况如下,查询其中的数据IO次数稳定
  • 数据分布不好的情况,查找数据IO次数不稳定,要找数据就需要IO次数很多,数据结构退化成链表

平衡二叉树

为了 防止 二叉树退化成链表 的最坏的情况,在符合二叉查找树的条件下,还满足任何节点的两个子树的高度最大差为1,这样就变成平衡二叉树(AVL树),需要注意的是平衡二叉树是每个节点只存储一个键值和数据的。

为了保证任何节点的两个子树的高度最大差为1,是通过各种旋转实现
平衡二叉查找树的特点:

  • 二叉查找树的平均时间复杂度为 O(log(N))
  • 每个节点最多只能有两个子节点
  • 每个节点的左右子树高度差不超过 1

平衡二叉查找树通过旋转可以使每个节点的左右子树高度差不超过 1,也就是避免链化问题。磁盘的 IO 由树高决定,数据量越多,遍历次数越多,IO 次数就越多,就越慢。

B-Tree

B-Tree 和平衡二叉树不一样,B-Tree 属于多叉树又名平衡多路查找树(查找路径不止两个)。

平衡二叉树 每个节点只有一个key,而多路合并之后的B-Tree每个节点含有一组key。这样整棵树的层级会变矮,可以针对外部查找大大减少I/O次数。这就解释了为什么已经有了 “平衡二叉树” 还弄个B-Tree。

B-Tree 特点:

(1)B-Tree每个节点含有一组key(而 平衡二叉树 每个节点只有一个key),这样压缩树的高度 ,减少I/O次数,提升查询速度

(2)叶子节点具有相同的深度(同B+Tree),页节点指针为空(B+Tree叶子节点有指针连接)

(3)所有索引元素不重复(B+Tree中非叶子节点有key的冗余),非叶子节点上有数据

(4)节点中的索引从左到右递增排列

B+Tree

B+Tree是在B-Tree基础上的一种优化,使其更适合实现外存储索引结构。B+Tree与B-Tree的结构很像,但是也有几个自己的特性:

(1)叶子节点具有相同的深度(同B-Tree),所有叶子节点之间都有一个链指针

(2)所有的非叶子节点只存储关键字(key)信息

(3)所有数据都存在叶子结点中

(4)节点中的索引从左到右递增排列

B+Tree 是 BTree 的一个变种,设 d 为树的度数,h 为树的高度,B+Tree 和 BTree 的不同主要在于:

B+Tree 中的非叶子结点不存储数据,只存储键值。
B+Tree 的叶子节点没有指针,所有键值都会出现在叶子节点上,且 key 存储的键值对应 data 数据的物理地址。
B+Tree 的每个非叶子节点由 n 个键值 key 和 n 个指针 point 组成

MySQL为什么最终要去选择B+Tree?

(1)B+Tree是B-Tree的变种,B-Tree能解决的问题,B+Tree也能够解决(降低树的高度,增大节点存储数据量)

(2)B+Tree扫库和扫表能力更强。如果我们要根据索引去进行数据表的扫描,对B-Tree进行扫描,需要把整棵树遍历一遍,而B+TREE只需要遍历他的所有叶子节点即可(叶子节点之间有引用)。

(3)B+Tree磁盘读写能力更强。他的根节点和支节点不保存数据区,所以根节点和支节点同样大小的情况下,保存的关键字要比B-Tree要多。所以,B+Tree读写一次磁盘加载的关键字比B-Tree更多。

(4)B+Tree排序能力更强。B+Tree天然具有排序功能。

(5)B+Tree查询性能稳定。B+Tree数据只保存在叶子节点,每次查询数据,查询IO次数一定是稳定的。当然这个每个人的理解都不同,因为在B-Tree如果根节点命中直接返回,确实效率更高。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值