B+树索引学习

1.谈B+树之前需要谈二叉排序树、二叉平衡术、B树,B+树就是从这三演化来的。

2.二叉排序树。

二叉查找树特性是结点值大于左子树结点值,小于右子树结点值,从根节点到叶子结点依次递归。对二叉排序树中序遍历可以得到递增有序的序列。采用二叉排序树作为索引结构,每个结点存储键值和数据,我们只需要查找树的高度次数即可找到结果。但存在一个问题,如果二叉排序树是单分支(只有右子树或左子树),则需要遍历整棵树,相当于全表扫描,则性能很差。

3.二叉平衡树

为解决树的高度过高,采用二叉平衡树,二叉平衡树在二叉排序树的基础上,左右子树的高度差不超过1,如果大于1则进行旋转调整保证高度差不超过1。二叉平衡树相比较二叉排序树更加稳定,速度更快。

这里我们需要谈一下磁盘,由于内存具有易失性,所以数据和索引存储在磁盘上。磁盘分为磁道,磁道分为扇区,每个扇区大小相同,可以称作磁盘块。但磁盘的速度相对于内存慢很多。将越多的数据存储在磁盘块上,则一次磁盘查找的数据就更多,查找效率更高,查找时间更少。采用二叉平衡树作为索引结构,由于平衡二叉树每个节点只存储一个键值和数据,则每个磁盘块存储一个键值和数据。如果二叉排序树的节点很多,高度很高,则需要进行很多次的磁盘IO,我们的查找效率将会很低。

4.B树

为解决二叉平衡树一个结点只存储一个键值和数据的弊端,B树一个结点存储多个键值和数据。B树的每个结点叫做页,MYSQL数据读取的基本单位就是页。

B树相对于二叉排序树每个结点存储更多的键值和数据,并且每个结点有更多的子结点,子结点的个数称为阶,B树的高度将更低,B树查找磁盘的次数将更少。

因为数据库中页(结点)大小固定的,InnoDB中页的默认大小是16KB,所以希望在固定的页中存放更多的结点个数。

5.B+树

为解决固定页中存放更多的结点个数,所以将B树中非叶子结点的数据和键值分离,非叶子结点值存储键值,将数据存放在叶子结点中,由此产生B+树。相对于B树,B+树结点可以存储更多的键值个数,树的阶将更大,树就会更矮更胖,磁盘IO次数将更少,效率将更高。

比如,B+树一个结点是1000个键值,那么三层B+树能存储1000*1000*1000=10亿个数据。一般根节点常驻内存,则只需两次IO就能查找10亿个数据。

因为B+树索引的所有数据存储在叶子结点且按序排列,所以使得范围查找、排序查找、分组查找更加简单,因为B树中结点存储数据,若采用范围查找则需对B树进行中序遍历得到有序序列才能进行查找。

B+树中各个结点之间通过双向链表连接,结点中的数据通过单向链表连接,InnoDB索引中就是这样存储的。

6.聚集索引和非聚集索引

Mysql中,B+树索引根据存储方式的不同分为聚集索引和非聚集索引。

聚集索引:

以InnoDB作为存储引擎的表中,表中数据都有一个主键,即使不创建主键,也会隐式创建主键。

数据存储在B+树中,键值就是主键,在B+树叶子结点中存储表中所有数据。以主键作为B+树索引键值构成的B+树索引,成为聚集索引。

非聚集索引:

以主键外的列作为B+树的键值构成的B+树索引成为非聚集索引。

两者区别在于非聚集索引叶子结点不存储数据,只存储该列对应的主键。想要查找数据还需根据主键去聚集索引中查找,根据主键去聚集索引中查找的过程叫做回表。

7.利用聚集索引和非聚集索引查找数据过程

SQL: select * from user where id>=18 and id <40(user表字段id、name,id为主键)

聚集索引查找过程:

首先根节点常驻内存,不需要去磁盘查找,直接读取。从根节点中我们找到18,18对应的指针页,从磁盘中加载到内存中,依次找下去,知道叶子结点,叶子结点中数据是顺序存放的,通过二分查找就可以定位到数据。因为所有的数据都是存放在叶子结点上且有序排列,所以根据找到的数据依次遍历即可查找满足条件的数据。

非聚集索引查找过程:

跟聚集索引查找过程一样,但叶子结点不存放数据,只存放主键值,所以找到主键后需要到聚集索引中查找对应数据。

总之数据即索引,索引即数据。

-----------------------------------------------------------------------------------------------------

学习原文:https://blog.csdn.net/qq_45814695/article/details/117171536

全部评论

相关推荐

1.&nbsp;自我介绍2.&nbsp;项目都是自己写的吗?3.&nbsp;我看你用&nbsp;koa2&nbsp;写后端,为什么选择它,能讲讲吗?4.&nbsp;那你提到&nbsp;koa2&nbsp;它是不提供中间件的,你是怎么解决的?5.&nbsp;中间件的原理是什么?(洋葱模型)6.&nbsp;你刚刚说碰到&nbsp;next()&nbsp;就进入下一个中间件,那&nbsp;next&nbsp;只能执行同步,如果是异步的话,你是怎么处理的?(async/await,但是我发现,有的中间件需要在异步中间件之前执行,所以我用&nbsp;try/catch&nbsp;来处理异步中间件的异常)7.&nbsp;JS&nbsp;异步发展史,以及它们的优缺点说一下&nbsp;(回调函数--Promise--Generator--async/await)8.&nbsp;你刚刚说&nbsp;Promise&nbsp;状态不能更改,那如果我要设计一个能修改&nbsp;Promise&nbsp;状态的函数,你会怎么设计?9.&nbsp;CSS&nbsp;水平垂直居中的方法(flex、grid、绝对定位&nbsp;+&nbsp;margin:auto、绝对定位&nbsp;+&nbsp;负&nbsp;margin、绝对定位&nbsp;+&nbsp;transform、table-cell)10.&nbsp;你刚刚说到&nbsp;flex&nbsp;布局,那&nbsp;flex:1&nbsp;是什么意思?(flex:&nbsp;flex-grow&nbsp;&nbsp;flex-shrink&nbsp;&nbsp;flex-basis;等价&nbsp;flex:1&nbsp;1&nbsp;0%表示元素可以均分剩余空间,可拉伸、可压缩,不依赖内容宽度,自动自适应填充布局。)11.&nbsp;父容器宽是&nbsp;500px,然后它左右各有两个子容器是&nbsp;100px,如果设置&nbsp;flex:&nbsp;1,那它的宽度是多少?(500-100-100=300px)12.&nbsp;说说你对浏览器缓存的理解(强缓存、协商缓存)13.&nbsp;如果一个用户,他怎么去刷新都无法刷到最新版的代码,你能说下可能的原因吗?(版本号、hash等)还有吗?(我说我不知道了,面试官说还有&nbsp;CDN&nbsp;没有同步,我说企业才会这么干,自己写项目一般不会,我知道&nbsp;cdn&nbsp;是用来解决高并发的手段)14.&nbsp;React你熟吗?说下&nbsp;React&nbsp;函数组件和类组件的区别15.&nbsp;怎么避免&nbsp;Hooks&nbsp;导致组件重新渲染?(使用&nbsp;useCallback、useMemo、React.memo、useRef等等)16.&nbsp;谈一下我对&nbsp;React&nbsp;的状态管理的理解(Redux、Mobx、Zustand,我说&nbsp;Zustand&nbsp;用的最多)17.&nbsp;React&nbsp;常见的&nbsp;hooks&nbsp;有哪些?(useState、useEffect、useRef、useCallback、useMemo、useReducer、useContext、useImperativeHandle、useLayoutEffect、useDebugValue)18.&nbsp;TS&nbsp;你熟吗?我们引进&nbsp;TS&nbsp;的目的是为什么?19.&nbsp;interface&nbsp;和&nbsp;type&nbsp;的区别20.&nbsp;说下&nbsp;TS&nbsp;里的泛型21.&nbsp;我现在有十个字段,比如十个字段就要&nbsp;A&nbsp;B&nbsp;C&nbsp;D&nbsp;E&nbsp;F&nbsp;G&nbsp;这种。那我现在另有另外一个方法,这个方法接受的参数呢,必须是这个&nbsp;interface&nbsp;A&nbsp;里面的这个&nbsp;K。就比如说你可以是&nbsp;A&nbsp;B&nbsp;C&nbsp;可以&nbsp;A&nbsp;B&nbsp;C&nbsp;D&nbsp;任何组合都可以,但是必须是这个&nbsp;interface&nbsp;里面的&nbsp;A&nbsp;里面的定义的。这个&nbsp;K&nbsp;这种类型的话是怎么去定义呢?(说实话我有点不太理解啥意思,反正我说了&nbsp;keyof)```&nbsp;TypeScriptinterface&nbsp;Obj&nbsp;{A:&nbsp;stringB:&nbsp;stringC:&nbsp;stringD:&nbsp;stringE:&nbsp;string//&nbsp;其他字段...}```22.&nbsp;vite&nbsp;用过吗?说说和&nbsp;webpack&nbsp;的区别。vite&nbsp;的优缺点是什么23.&nbsp;说说&nbsp;Tree&nbsp;shaking(树摇)&nbsp;和&nbsp;Code&nbsp;Splitting&nbsp;(代码分割)的区别24.&nbsp;Git&nbsp;你熟吗?说说&nbsp;git&nbsp;merge&nbsp;和&nbsp;git&nbsp;rebase&nbsp;的区别,什么时候用&nbsp;git&nbsp;merge,什么时候用&nbsp;git&nbsp;rebase?25.&nbsp;web3&nbsp;你熟吗?(不太熟,听说过而已)26.&nbsp;我看你自我介绍说了&nbsp;AI,你是怎么用的?27.&nbsp;除了提示词,还有什么能让&nbsp;AI&nbsp;更聪明?28.&nbsp;AI&nbsp;的优缺点你说一下29.&nbsp;AI&nbsp;发展这么快,你觉得我们以后会扮演什么角色?30.&nbsp;反问基本都答上来了。面了我80分钟,我还以为稳过的
查看29道真题和解析
点赞 评论 收藏
分享
评论
3
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务