Mysql的索引为什么使用B+Tree

Mysql的索引为什么使用B+Tree

四个问题
为什么要设计索引?
如果是你,改如何设计索引?
设计索引的时候使用什么数据结构?
Mysql的索引是如何实现的?

一、mysql的存储引擎
show engines; 可以查看mysql所使用的的存储引擎,因为不同的索引是构建在不同的存储引擎之上的。
在这里插入图片描述
1:如上图,用的最多的三种就是:

InnoDB(B+树,支持自适应hash,没法人为的去改变)。
MyISAM(B+树)。
MEMORY(hash)。

2:InnoDB为什么不使用其他数据结构,而且选择了B+树

A:假如使用hash,就需要考虑hash值的冲突问题,需要设计非常好的一个hash算法,需要将数据均匀的分布,所以不太合适。
B:利用hash存储的话需要将所有的数据添加到内存中,比较耗费内存资源。
C:等值查询hash的方式速度的确很快,但是范围查询就不合适。但是MEMORY就使用的是hash,因为他是基于内存的。
D:无论是二叉树还是红黑树,因为节点上存储的就是数据,查询的时候由于数据量的增加树的深度会无限的增变深,,从而造成了IO次数变多,影响数据读取的效率。
E:B树的样例结构如下图
在这里插入图片描述
数据29查询的过程:
根据根节点找到16K(InnoDB规定的大小)大小的磁盘块1,,比较29在哪个区间,找到磁盘块1的指针P2,根据P2指针找到磁盘块3,然后比较29在26-30之间,就找到磁盘块3的指针P2,然后通过磁盘块3的指针P2找到磁盘块7然后找到对应的数据
其实可以看出在一定的存储空间下,由于每一个磁盘块中都有紫色的data,浪费了很对空间,导致B树结构存储不了多少数据,所有才有了后面的B+树,干掉了非叶子节点的data,节省了很多空间

FB+树的样例图
在这里插入图片描述
由于将数据将B树中的data节点省略掉了,节省了很多空间,所以一个磁盘块也就是数据库中的page页中可以存储更多的指针和主键值(不是数据库表的主键)。
在B+树上有两个头指针,一个指向根节点,另一个指向关键字最小的叶子节点,而且所有的叶子节点(数据节点)之间是一种链式环形结构,因此可以对B+树有两种查找运算方式,一种是通过根节点开始,进行随机查找,另一种是对于主键范围查找和分页查找

所以生产中设计索引时,尽量使用int类型的字段,因为int占用的空间相对较少,可以减少B+树的深度,也就较少了IO的次数,所以索引越小越好
在B+数据的索引结构中,查找数据可以通过根节点一层一层的查找,还有一种就是底层是一个双向链表,可以基于双向链表,从做开始到结束进行顺序查找,至于用哪种方式,mysql的优化器会来选择。因为数据存储是有序的,在数据插入的时候会组织数据。

二、综上所述mysql的中索引选择了B+树

1、但是要注意的是MyISAMInnoDB都是采用的**B+**树的存储结构,但是他们的差异就是在叶子节点的data中,他们存的数据不是一个东西InnoDB的data中放的就是实际的表的数据,但是MyISAM放的是数据的地址,需要根据这个地址读取数据的所在行

2、上图中的键值也就是那个key值说明:
AInnoDB是通过B+树结果对主键创建索引,然后叶子节点存储数据,如果没有主键,就会选择唯一键,如果没有唯一键,那么就会生成一个6字节的row_id来作为主键,row_id对用户不可见。
BInnoDB是使用的聚簇索引,MyISAM使用的是非聚簇索引,如果创建索引的键是其他字段,那么在叶子节点中存储的是该记录的主键,然后再通过主键索引来查找数据例如id是主键,name列上创建了索引,那么通过name查询时,先会通过name找到id,然后通过id再去查找出数据
C主键是否需要设置成自增的,要是单机的数据库,非常建议,因为自增的主键会让数据一直往树的最右边插入,要是是索引是乱序的,就有可能往树的中间的某个节点中插入,这样有可能会导致树的页分裂和页合并,而且还会影响索引节点,索引的维护成本会很高。要是集群,就不太建议了,分布式的可以自己指定主键生成策略,或者使用雪花算法等。

====================备注:后续会更新mysql的优化--------------------------------

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值