MySQL B+树索引 和 Redis 中跳表索引的区别

一、MySQL B+树索引 和 Redis 中跳表索引

MySQL 中常用的索引是 B+树索引,而 Redis 中,例如 zset 使用的的是跳表索引,两者有什么区别呢,MySQL 为什么不使用 跳表 呢?或者说 Redis 中为什么不使用 B+树 呢?

下面先分别了解下 B+树和跳表的工作原理。

二、B+树

B+树是 B树的变体,B+树对比 B树,将B树的一个节点同时存放主键和数据的形式,改为叶子节点和非叶子节点形式。其中非叶子节点不存储具体数据,只存放主键和指向下一级数据的指针。而叶子节点在最尾端,存放主键和指向数据行的地址。叶子节点和非叶子节点采用指针连接,提高区间访问的性能。结构如下:

在这里插入图片描述

MySql 每次从磁盘读取数据是以页的形式读取,默认一页的大小为16k。这里假设每个主键占用8个字节,指针占6个字节,那么mysql 一次从磁盘读取 16k 就可以拿到 1024*16/(8+6)= 1170 条数据,假设树的高度为两级,这两次磁盘 IO 操作就可以大概涵盖 1170*1170 =1368900 查不到一百多万条数据,由此可见 B+树 效率之高。

此外 B+ 树能保证如此高的查询性能,关键点还在于B+树结构的平衡,这样就需要在插入数据的时候额外计算和调整树的平衡操作,一定程度降低了写的性能,下面来看下写的过程。

比如,当一个树节点最多可以存放5个索引的时候,在写入前 5 个数据的时候都不会触发树的平衡:

在这里插入图片描述

但是写入第6个数据的时候,因为一个节点最大放5个索引,所以下一步需要平衡,只能拆成二级结构:

在这里插入图片描述
由于最大的节点中有三个索引,所以下面两次写入,都不会触发平衡:

在这里插入图片描述
再次写入的时候,就需要进行平衡了,但是最上层的节点只有一个索引,所以可以在第一层加一个索引,第二层分三个节点:

在这里插入图片描述
依次类推,可以极大的较少树的层级。

所以 B+ 树通过空间换时间的方式,使用不同的叶子结点构建索引层级,将查询的时间复杂度从全表检索的O(n) 优化为O(lg(n))

三、跳表

跳表是一个随机化的数据结构,实质就是一种可以进行二分查找的有序链表。跳表在原有的有序链表上面增加了多级索引,通过索引来实现快速查找。跳表不仅能提高搜索性能,同时也可以提高插入和删除操作的性能。

在这里插入图片描述

例如上述结构,假如需要查询主键为 7 的数据,首先在第一层从左向右可以找出在 6 之后、11 之前,然后进到 6 的下一层,继续从左向右可以找出在 6 之后、8 之前,然后进到 6 的下一层,从左向右就可以找到 7 了。

整体有点类似二叉树,但最后一层是全部的数据,上层通过增加跳跃点的方式加速检索的过程,并且跳跃点采用随机概率的方式决定是否增加,如果是两层跳跃层的话,在第一层加索引的概率就是 50% 概率,到第二层就是 25% 的概率 ,这样如何数据量样本足够大的话,数据的分布可以基本达到二分的效果。

由于每次写入数据,都随机决定是否要在每层增加索引,所以写入效率非常高。

例如写入数据9,首先在最后一层新增数据:

在这里插入图片描述

四、总结

MySQL 是磁盘存储的数据库系统,其中性能瓶颈在于磁盘IO的性能,而 B+树,以叶子节点和非叶子节点存储多索引的方式极大降低树的层级,在磁盘访问时能够保持较好的局部性,也大大降低了磁盘的读取次数,可以有效提升读取的性能。而跳表由于其随机指针的特性,在磁盘访问时可能导致更多的随机IO操作,影响访问效率。跳表在存储空间利用率上也不占优势。跳表需要维护多级索引,可能会导致额外的空间消耗,尤其是在数据量较大时,这种空间开销会变得非常显著。因此对比下来, B+树更适合 MySQL

Redis 是基于内存的数据库,数据操作都在内存中进行,无需关注磁盘IO,所以即使层级增大也影响不大,但是 B+树写数据时需要进行树平衡操作,反而影响了写的性能。而且跳表相对于B+树来说实现更加简单,代码量更少,容易理解和维护。在内存数据库中,简单且高效的实现是非常重要的考虑因素。跳表在支持范围查询方面比较灵活,插入、删除和查找操作的时间复杂度都是O(log n),这使得跳表在处理范围查询时表现较好。因此对比下来 Reids 中跳表的效果更好。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/766917.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

章节10实验--Ubuntu18.04 Qt MySQL libqsqlmysql.so

前言: 内容参考《操作系统实践-基于Linux应用与内核编程》一书的示例代码和教材内容,所做的读书笔记。本文记录再这里按照书中示例做一遍代码编程实践加深对操作系统的理解。 引用: 《操作系统实践-基于Linux应用与内核编程》 作者:房胜、李旭健、黄…

golang 对接第三方接口 RSA 做签(加密) 验签(解密)

一、过程 1.调用第三方接口前,一般需要按规则将参数按key1value1&key2value2 阿斯克码排序,sign参数不参与加密 2.将排序并连接好的参数字符串通过我方的私钥证书(.pem)进行加密得到加密串,当然加密得到的是 []byte 字节流&…

看完就等于拿捏浮点数在内存中的储存了

诸君又该学习了,今天我们继续来一睹浮点数的奥妙真容。 经过前面文章对整形提升相关的解释,我们都对整形和字符在内存空间上的储存已经有了大概的认知,那么现在我们就来好好讲讲浮点数在内存中的储存规则。 目录 浮点数与整形储存的不同 …

41-Vue-webpack基础

webpack基础 前言什么是webpackwebpack的基本使用指定webpack的entry和output 前言 本篇开始来学习下webpack的使用 什么是webpack webpack: 是前端项目工程化的具体解决方案。 主要功能:它提供了友好的前端模块化开发支持,以及代码压缩混淆、处理浏览…

自定义序列化

3.2.2.自定义序列化 RedisTemplate可以接收任意Object作为值写入Redis: 只不过写入前会把Object序列化为字节形式,默认是采用JDK序列化,得到的结果是这样的: 缺点: 可读性差内存占用较大 我们可以自定义RedisTempla…

NASA数据集——2015 年30 米分辨率的地衣地面覆盖率模型估计值

cABoVE: Lichen Forage Cover over Fortymile Caribou Range, Alaska and Yukon, 2000-2015 文件修订日期:2021-07-21 数据集版本: 1 摘要 本数据集提供了美国阿拉斯加东部内陆和加拿大育空地区 Fortymile 研究区 2015 标称年 30 米分辨率的地衣地面覆盖率模型估…

YOLOv8-ROS-noetic+USB-CAM目标检测

环境介绍 Ubuntu20.04 Ros1-noetic Anaconda-yolov8虚拟环境 本文假设ROS和anaconda虚拟环境都已经配备,如果不知道怎么配备可以参考: https://blog.csdn.net/weixin_45231460/article/details/132906916 创建工作空间 mkdir -p ~/catkin_ws/srccd ~/ca…

湖北专升本报名照片需要<40kb怎么解决

湖北专升本报名照片需要<40kb怎么解决

vue 修改element-plus主题色

一、安装SCSS npm install sass --save-dev npm install sass-loader --save-dev npm install node-sass --save-dev npm install vue-style-loader --sava-dev 二、添加主题文件theme.scss forward "element-plus/theme-chalk/src/common/var.scss" with ($col…

kubernetes负载均衡-service

一、service的概念 1、什么是service 在Kubernetes中&#xff0c;pod是应用程序的载体&#xff0c;当我们需要访问这个应用时&#xff0c;可以通过Pod的IP进行访问&#xff0c;但是这里有两个问题:1、Pod的IP地址不固定&#xff0c;一旦Pod异常退出、节点故障&#xff0c;则会…

【STM32】读写BKP备份寄存器RTC实时时钟

目录 BKP BKP简介 BKP基本结构 BKP测试代码 RTC RTC简介 RTC框图 RTC基本结构 硬件电路 RTC操作注意事项 接线图 初始化 使用BKP解决只初始化一次时间 初始化参考代码 RTC设置时间 RTC读取时间 完整代码 MyRTC.c MyRTC.h main.c BKP BKP简介 BKP&#xff0…

pytorch中tensor类型转换的几个函数

目录 IntTensor转FloatTensor FloatTensor转IntTensor Tensor类型变为python的常规类型 IntTensor转FloatTensor .float函数&#xff1a; FloatTensor转IntTensor .int函数 Tensor类型变为python的常规类型 item函数

阿里云部署MySQL、Redis、RocketMQ、Nacos集群

文章目录 &#x1f50a;博主介绍&#x1f964;本文内容MySQL集群配置云服务器选购CPU选择内存选择云盘选择ESSD AutoPL云盘块存储性能&#xff08;ESSD&#xff09; 镜像选择带宽选择密码配置注意事项 安装docker和docker-compose部署MySQL三主六从半同步集群一主二从同步集群规…

pytorch如何向tensor结尾添加元素或维度--torch.cat()、torch.unsqueeze()的用法

目录 示例1 矢量后增加元素 示例2 tensor维度增加1 示例3 另一种替代unsqueeze的方法 示例1 矢量后增加元素 使用torch.cat()函数 ptorch.Tensor([1,5,0]) ptorch.cat((p, torch.Tensor([4])), 0) 结果&#xff1a; 这里&#xff0c;cat的第一个输入变量用()包绕&#xf…

Request请求参数----中文乱码问题

一: GET POST获取请求参数: 在处理为什么会出现中文乱码的情况之前, 首先我们要直到GET 以及 POST两种获取请求参数的不同 1>POST POST获取请求参数是通过输入流getReader来进行获取的, 通过字符输入流来获取响应的请求参数, 并且在解码的时候, 默认的情况是 ISO_885…

由浅到深认识Java语言(21):Math类

该文章Github地址&#xff1a;https://github.com/AntonyCheng/java-notes 在此介绍一下作者开源的SpringBoot项目初始化模板&#xff08;Github仓库地址&#xff1a;https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址&#xff1a;https://blog.c…

GaussDB WDR分析之集群报告篇

AWR报告目前已经成为Oracle DBA分析问题&#xff0c;定位故障最为重要的报告&#xff0c;阅读与分析AWR报告的技能也是Oracle DBA必备的技能。国产数据库为了提高运维便捷性&#xff0c;都在做类似Oracle AWR报告的模仿&#xff0c;只不过由于指标体系不够完善&#xff0c;因此…

postman 用上一个请求的响应体中的字段设置下一个请求的请求参数

文章目录 IntroPostman usagePre-request ScriptTests javascripts API Intro 这一切都是为了增加自动化动作所占的比例&#xff08;减少人手工操作复制粘贴可能会造成的错误&#xff09;。 Postman usage 最常用的&#xff1a;选HTTP方法类型、写URL&#xff0c;在Headers中…

如何解决Layui后台接口返回数据,但是table.render不渲染表格数据的问题

我这边进行了pareData数据格式转换&#xff0c;response重新定义了layui的参数格式规范 接口正常返回了数据 但是就是不渲染&#xff0c;我这个郁闷啊&#xff01;&#xff01; 忽然&#xff0c;我把后台重新定义的layui规定的格式参数&#xff0c;有个参数名叫data&#xff0…

sql注入五-WEB攻防-注入工具SQLMAPTamper编写指纹修改高权限操作目录架构

演示案例&#xff1a; 数据猜解-库表列数据&字典权限操作-文件&命令&交互式提交方法-POST&HEAD&JSON绕过模块-Tamper脚本-使用&开发分析拓展-代理&调试&指纹&风险&等级 #参考&#xff1a; https://www.cnblogs.com/bmjoker/p/9326258.…