MySql中的索引与B+树


在mysql使用中,经常会用到索引,但是起初并不理解索引到底是什么,数据结构是什么样子,和表怎么关联,为什么能提升效率。

一、问答

索引是什么?

答:索引是一张数据表指定字段的数据组成的B+树。比如默认使用主键id作为索引时,主键的值将会组成一个B+树的非叶子节点,而叶子节点则存储具体的行数据,用来提升数据库检索速度。

InnoDB存储数据也是用B+树,两者有什么关系?

答:分两种情况,是否使用主键索引:
第一种:使用主键索引时,存储数据的B+树就是索引的B+树,两者是同一个。
第二种,使用非主键索引(二级索引或辅助索引,包括联合索引)时,会根据索引字段的数据生成一个新的B+树,与存储表数据的B+树是两个相互独立的。

使用非主键索引时,索引B+树有什么不同

答:最主要的不同是非主键索引B+树的叶子节点不存储行数据,而是存储了对应行的主键值,用于关联两个B+树,因此会衍生出回表操作。即 使用非主键索引查询时,先在存储索引数据的B+树中查到目标行的主键值,再去存储表数据的B+树中查询对应的行数据,这就是回表。

为什么要用B+树,而不是B树或是二叉树

答:这个问题需要反向解释,先解释二叉树和B树的缺点,自然就清晰了。
二叉树:将数据以二分查找法的思路进行父子关联,形成有规律的层级树,每个节点有两个子节点。缺点:1、数据多了之后,层级会很多,2、可能会出现某个节点下存在大量数据,造成树的失衡,甚至形成一个链表。
平衡二叉树:是二叉树的升级版,可以根据数据进行调整顶层节点,保证树整体左右的平衡,防止某个节点下积累大量数据,造成树的失衡。但是 仍然无法解决数据多了之后,层级过多的问题。
B树:不同于二叉树和平衡二叉树的叶子节点只存储一组数据,B树的叶子节点存储多个数据,如[1,2,3,4,5,6,7,8,9],顶级节点不是单独的5,可以是[ 4,8 ],那么二层可以分层四个节点,分别是[1,2,3],[5,6,7],[9],这样可以极大的缩小树的层级,减少IO次数。
缺点:1、查询效率不稳定,因为数据存储在每个节点中,靠近根节点查询速度快,叶子节点查询速度慢,2、如果是范围查询,则需要多个节点反复IO,速度较慢
B+树:为了避免范围查询在节点中的反复IO和查询效率不稳定,所有数据都存储在叶子节点,非叶子节点只存储索引值,可以保证查询效率的稳定。而叶子节点再用指针连接,形成了双向链表,就可以轻松解决范围查询问题。

叶子节点的指针是怎么连接叶子节点的?

答: 叶子节点不仅存储了多个行数据,下一个叶子节点和上一个叶子节点的指针。
指针实际上是硬盘地址的引用,而指向的是数据页在硬盘的存储位置。当innoDB访问某个数据时,如果属于内存的BufferPool中不存在,则会根据指针将数据页加载到BufferPool中,然后进行高效的操作,减少和硬盘的IO交互。
当数据发生变化,需要重新写回硬盘的时候,依旧需要根据指针写回对应的硬盘位置进行持久化。

使用指针连接叶子节点后,innodb如何保证B+树的平衡性

答:保证B+树叶子节点的平衡性主要在于对数据页的管理,因为数据页是固定大小(默认16k,可以使用innodb_page_size修改),当数据量达到上限时,会进行拆分数据页,同时将两个数据页也用各自的指针进行连接,保证了链表的连续性。同时也会修改父级节点针对子节点的指针。
如果删除数据时清空了某些叶子节点,则会清理这些节点以及修改前后节点的连接指针,同时父级节点存储的子节点指针。

如果以上内容中有错误,欢迎大家留言或私信指出。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值