B+树 -- MySQL数据库索引

文章目录

    • 1. 定义清楚问题
    • 2. 尝试学过的数据结构解决问题
    • 3. 改造二叉查找树来解决问题
    • 4. 总结

为了加速数据库中数据的查找速度,我们常对表中数据创建索引。数据库索引是如何实现的呢?底层使用的是什么数据结构和算法呢?

1. 定义清楚问题

如何定义清楚问题呢?除了问题调研,还可以对一些模糊的需求进行假设,来限定要解决的问题的范围。

假设要解决的问题,只包含两个常用的需求:

  • 根据某个值查找,比如 select * from user where id = 1234
  • 根据区间来查找,比如 select * from user where id > 1234 and id < 2345

非功能性需求,比如安全、性能、用户体验等等。性能方面,主要考察时间和空间两方面,就是执行效率和存储空间。

  • 在执行效率方面,希望通过索引,查询数据的效率尽可能的高;
  • 在存储空间方面,希望索引不要消耗太多的内存空间。

2. 尝试学过的数据结构解决问题

支持快速查询、插入等操作的动态数据结构,已经学过散列表、平衡二叉查找树、跳表。

  • 散列表。散列表的查询性能很好,时间复杂度是O(1)。但是,散列表不支持按照区间快速查找数据。
  • 平衡二叉查找树。尽管平衡二叉查找树查询的性能也很高,时间复杂度是O(log n)。对树进行中序遍历,还可以得到一个从小到大有序的序列,但不足以支持按照区间快速查找数据。
  • 跳表。跳表是在链表之上加上多层索引构成的。它支持快速地插入、查找、删除数据,对应的时间复杂度是O(log n)。并且,跳表也支持按照区间快速地查找数据。只需要定位到区间起点值对应在链表中的结点,然后从这个结点开始,顺序遍历链表,直到区间终点对应的结点为止。
    在这里插入图片描述

这样看来,跳表是可以解决这个问题。实际上,数据库索引所用到的数据结构跟跳表非常相似,叫作B+树。不过,它是通过二叉查找树演化来的。

3. 改造二叉查找树来解决问题

为了让二叉查找树支持按照区间查找数据,对它进行改造:树中的节点并不存储数据本身,而是只是作为索引。除此之外,我们把每个叶子节点串在一条链表上,链表中的数据是从小到大有序的。
在这里插入图片描述
改造后,要查某个区间的数据。只需拿区间的起始值,在树中进行查找,当查找到某个叶子节点之后,再顺着链表往后遍历,直到链表中的结点数据值大于区间的终止值为止。所有遍历到的数据,就是符合区间值的数据。
在这里插入图片描述
但是,要为几千万、上亿的数据构建索引,将索引存储在内存中,尽管内存访问速度非常快,查询效率非常高,但是,占用的内存非常多

比如,给一亿个数据构建二叉查找树索引,索引中大约1亿个节点,每个节点假设占用16个字节,要大约1GB的内存。给一张表建立索引,需要1GB的内存。如果要给10张表建立索引,那对内存的需求是无法满足的。如何解决这个索引占用太多内存的问题呢?

可以借助时间换空间的思路,把索引存储在硬盘中,而非内存中。硬盘非常慢。通常内存访问纳秒级,而磁盘访问毫秒级。将索引存储在硬盘中,尽管减少了内存消耗,但是数据查找,需读取磁盘中的索引,因此查询效率降低很多。

二叉查找树,经过改造之后,支持区间查找的功能就实现了。节省内存,把树存储在硬盘中,每个节点的读取(或者访问),对应一次磁盘IO操作。树的高度等于每次查询数据时磁盘IO操作的次数

所以优化的重点就是尽量减少磁盘IO操作,也就是, 尽量降低树的高度 。如何降低树的高度呢?

如果把索引构建成m叉树,高度是不是比二叉树要小呢?
如图所示,给16个数据构建二叉树索引,树的高度是4,查找一个数据,就需要4个磁盘IO操作(如果根节点存储在内存中,其他结点存储磁盘),
如果对16个数据构建五叉树索引,那高度只有2,查找一个数据,对应只需要2次磁盘操作。
如果m叉树中的m是100,那对一亿个数据构建索引,树的高度也只是3,最多3次磁盘IO就能取到数据。磁盘lO少了,查找效率也就高了。
在这里插入图片描述
m叉树中的m越大,那树的高度就越小,那m叉树中的m是不是越大越好呢?多大才最合适?

不管是内存数据,还是磁盘数据,操作系统都是按页(一页大小通常是4KB,这个值可以通过 getconfig PAGE_SIZE命令查看)来读取的,一次会读一页的数据。如果要读取的数据量超过一页的大小,就会触发多次IO操作。所以,我们在选择m大小的时候,要尽量让每个节点的大小等于一个页的大小。读取一个节点,只需一次磁盘IO操作。
在这里插入图片描述
尽管索引提高数据库查询效率,索引有利也有弊,它也会让写入数据的效率下降。这是为什么呢?

数据写入过程,会涉及索引的更新,这是主要原因。

对于B+树来说,m值是根据页的大小事先算好的,也就是说,每个节点最多只能有m个子节点。往数据库写入过程中,有可能使某些节点的子节点个数超过m,这个节点的大小超了一个页的大小,读取这个节点,就会导致多次磁盘IO操作。该如何解决?

处理思路并不复杂。只需将这个节点分裂成两个节点。但是,节点分裂之后,上层父节点的子节点个数可能超过m个。用同样的方法,将父节点也分裂成两个节点。这种级联反应会从下往上,一直影响到根节点。

这个分裂过程,可以结合下图,会更容易理解(图中的B+树是一个三叉树。限定叶子节点中,数据个数超过2个就分裂节点;非叶子节点中,子节点的个数超过3个就分裂节点)。
在这里插入图片描述
因为要时刻保证B+树索引是一个m叉树,索引的存在会导致数据库写入速度降低。删除数据也会变慢。为什么呢?

删除数据时,也要更新索引节点。频繁删除,导致某些结点中,子节点个数变得非常少,长此以往,如果每个节点的子节点都比较少,势必会影响索引的效率。

可以设置一个阈值。在B+树中,这个阈值等于m/2。某个节点的子节点个数小于m/2,将它跟相邻的兄弟节点合并。不过,合并之后结点的子节点个数有可能会超过m再分裂节点。

文字不直观,举个删除例子,(图中的B+树是一个五叉树。限定叶子节点中,数据少于2个就合并节点;非叶子节点中,子节点少于3个就合并)
在这里插入图片描述
B+树的结构和操作,跟跳表非常类似。理论上,对跳表稍加改造,也可以替代B+树。

4. 总结

  • 数据库索引实现,依赖的底层数据结构,B+树。
  • 通过存储在磁盘的多叉树结构,做到了时间、空间的平衡,既保证了执行效率,又节省了内存。

总结一下B+树的特点:

  • 每个节点中子节点的个数不超过m,也不小于m/2
  • 根节点的子节点个数可以不超过m/2,这是一个例外;
  • m叉树只存储索引,并不存储数据,这个有点儿类似跳表;
  • 通过链表将叶子节点串在一起,可以方便按区间查找;
  • 一般情况,根节点会被存储在内存中,其他节点存储在磁盘中

简单提一下。
B- 树就是B树,英文翻译都是B-Tree,这里的 “-” 不是相对B+树中的“+”,只是一个连接符。这个很容易误解。

B树实际上是低级版的B+树,或者说B+树是B树的改进版。B树跟B+树的不同点主要集中在这几个地方:

  • B+树中的节点不存储数据,只是索引,而B树中的节点存储数据;
  • B树中的叶子节点并不需要链表来串联。

也就是说,B树只是一个每个节点的子节点个数不能小于m/2的m叉树。

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

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

相关文章

创建python的虚拟环境(图文教程),并使用。

创建python的虚拟环境 第一步&#xff1a;打开anaconda命令行&#xff0c;即打开anaconda prompt。 base的主环境切换到虚拟环境nlp (base) C:\Users\user>conda env list 查看环境列表 (base) C:\Users\user>conda create -n nlp python 创建一个虚拟环境&#xff0…

领域应用 | 到底什么时候使用图数据库?

本文转载自公众号&#xff1a;TigerGraph。图数据库作为近两年快速发展的新型数据受到了市场极大的关注。但对于很多行业而言&#xff0c;图数据库还是一个很新的概念&#xff0c;企业管理人员和技术人员面临着同样的问题&#xff1a;企业的业务适不适合使用图&#xff1f;到底…

常用的后端性能优化六种方式:缓存化+服务化+异步化等

后端优化的六种方法&#xff1a; 1.硬件升级 硬件问题对性能的影响不容忽视。 举一个例子&#xff1a;一个DB集群经常有慢SQL报警&#xff0c;业务排查下来发现SQL都很简单&#xff0c;该做的索引优化也都做了。后来DBA同学帮忙定位到问题是硬件过旧导致&#xff0c;将机械硬…

有钱可以多任性?OpenAI提出人肉模型训练,文本摘要全面超越人类表现!

文 | 小轶背景三个多月前&#xff0c;OpenAI的GPT-3在NLP界掀起轩然大波。就在上周&#xff0c;视金钱如粪土的OpenAI团队又在文本摘要方面推出了最新力作&#xff0c;全方位超越人类表现。其亮点在于&#xff1a;以人类偏好替代自动化评测方法&#xff08;如ROUGE、BLUE&#…

数据挖掘第一次作业

我先大概写了写&#xff0c;还有一些读过的论文没有往上放&#xff0c;一些论文之间的联系线条没有搞出来。 就先这样吧&#xff01;有空再搞&#xff0c;我现在想去玩板子啦&#xff01;

A*搜索算法--游戏寻路

文章目录1. 算法解析2. 总结仙剑奇侠传这类MMRPG游戏中&#xff0c;有人物角色 自动寻路功能。当人物处于游戏地图中某位置时&#xff0c;点击另一个相对较远的位置&#xff0c;人物就会自动地绕过障碍物走过去。这个功能是怎么实现的呢&#xff1f;1. 算法解析 这是一个非常典…

阿里P8架构师谈:应用后端+移动端的性能优化指标,以及性能优化方法

性能优化专题 阿里P8架构师谈&#xff1a;MySQL数据库的索引原理、与慢SQL优化的5大原则 阿里P8架构师谈&#xff1a;Web前端、应用服务器、数据库SQL等性能优化总结 大型网站Web前端优化最佳实践&#xff0c;以及最全优化工具集锦 阿里P8架构师谈&#xff1a;多线程、架构、…

无主题

厦门月亮少 20191003 之前突然遇到个bug&#xff0c;解决好久无果&#xff0c;开始干点别的事情&#xff0c;大约四天后的今天&#xff0c;我打开程序想解决一下&#xff0c;然后&#xff0c;调试半天无果&#xff0c;妈妈突然微信和我聊天了&#xff0c;聊完以后往终端一瞥&a…

PyTorch Trick集锦

文 | z.defying知乎来源 | https://zhuanlan.zhihu.com/p/76459295前言本文整理了13则PyTorch使用的小窍门&#xff0c;包括了指定GPU编号、梯度裁剪、扩展单张图片维度等实用技巧&#xff0c;能够帮助工作者更高效地完成任务。1、指定GPU编号2、查看模型每层输出详情3、梯度裁…

论文浅尝 | 利用推理链进行视觉问题回答

论文笔记整理&#xff1a;吴杨&#xff0c;浙江大学计算机学院&#xff0c;知识图谱、NLP方向。http://papers.nips.cc/paper/7311-chain-of-reasoning-for-visual-question-answering.pdf动机在视觉问题回答中&#xff0c;较为复杂的问题经常需要多步骤的推理才能够回答&#…

阿里P8架构师谈:数据库、JVM、缓存、SQL等性能调优方法和原则

编辑 性能优化基本是BAT等一线互联网公司程序员必备的技能&#xff0c;以下为大家完整揭晓性能完整的优化方案和方法&#xff1a;包含web网站调优、数据库、JVM调优、架构调优等方案。 第一&#xff1a;Web网站调优 1、尽可能减少HTTP请求&#xff1a;图片合并 &#xff08;cs…

知乎招聘搜索算法实习生!邀你共建知乎搜索引擎!

星标/置顶小屋&#xff0c;带你解锁最萌最前沿的NLP、搜索与推荐技术部门介绍搜索算法团队是知乎核心算法团队之一&#xff0c;负责知乎搜索框背后的各项算法工作。我们团队一直非常重视新技术在搜索场景的探索和落地&#xff0c;包括但不限于 NLP&#xff0c;排序&#xff0c;…

论文浅尝 | 主题感知的问答生成

Citation: XingC, Wu W, Wu Y, et al. Topic aware neural response generation[C]//Thirty-FirstAAAI Conference on Artificial Intelligence. 2017.动机人机对话在 AI 和 NLP 领域是一项具有挑战性的工作。现存的对话系统包括任务导向的对话系统和非任务导向的聊天机器人。在…

.halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复

尊敬的读者&#xff1a; 网络安全是当今数字时代的一大挑战&#xff0c;各种勒索病毒如.halo病毒层出不穷&#xff0c;对用户和企业的数据安全构成了严重威胁。本文将介绍.halo勒索病毒&#xff0c;以及如何恢复被其加密的数据文件&#xff0c;同时提供预防措施。在面对被勒索…

阿里P8架构师谈:多线程、架构、异步消息、Redis等性能优化策略

常见性能优化策略分类 1.代码 之所以把代码放到第一位&#xff0c;是因为这一点最容易引起技术人员的忽视。很多技术人员拿到一个性能优化的需求以后&#xff0c;言必称缓存、异步、JVM等。实际上&#xff0c;第一步就应该是分析相关的代码&#xff0c;找出相应的瓶颈&#xf…

周志华教授专著《集成学习:基础与算法》上市,豆瓣满分森林书破解AI实践难题...

近年来&#xff0c;机器学习技术的快速发展推动了语音、自然语言处理、机器视觉等多个领域获得巨大进步&#xff0c;也带动了人工智能相关产业的蓬勃发展。回顾机器学习最近30 年的发展历程&#xff0c;各种学习方法推陈出新、不断演进。但是&#xff0c;在此历程中&#xff0c…

Redis常用数据类型的数据结构

文章目录1. Redis 数据库介绍2. 列表&#xff08;list&#xff09;3. 字典&#xff08;hash&#xff09;4. 集合&#xff08;set&#xff09;5. 有序集合&#xff08;sortedset&#xff09;6. 数据结构持久化7. 总结1. Redis 数据库介绍 Redis 是一种键值&#xff08; Key-Val…

论文浅尝 | 使用循环神经网络的联合事件抽取

余博涛&#xff0c;南京大学计算机科学与技术系&#xff0c;硕士研究生论文连接&#xff1a;http://www.aclweb.org/anthology/N16-1034发表会议&#xff1a;NAACL-HLT 2016摘要事件抽取&#xff08;event extraction&#xff09;是信息抽取中一个特别具有挑战性的问题。针对该…

阿里P8架构师谈:Web前端、应用服务器、数据库SQL等性能优化总结

web前端性能优化 Web前端指网站业务逻辑之前的部分&#xff0c;包括&#xff1a; 1.浏览器加载 2.网站视图模型 3.图片服务 4.CDN服务等 主要优化手段有优化浏览器访问&#xff0c;使用反向代理&#xff0c;CDN等。 1.浏览器访问优化 &#xff08;1&#xff09;减少http…

动手做个DialoGPT:生成式多轮对话模型

文 | 苏剑林编 | 兔子酱前段时间刷Arixv的时候&#xff0c;发现清华大学开源了一个大规模的中文闲聊语料库LCCC&#xff0c;从开源的文件上来看&#xff0c;这可能是目前开源的数量最大、质量最好的闲聊语料库了&#xff0c;而且还包含了部分多轮对话聊天&#xff0c;总的来说可…