MYSQL - 索引详解

一 什么是索引?

        实际上在上一篇介绍MYSQL的体系结构当中我们稍微提及了一点,在引擎层,我们提到不同的引擎对应的索引的实现方式,选择是不一样的。

        简单理解,索引(index)其实就是一种帮助MYSQL高效的获取数据的数据结构(有序排列),说到数据结构就会想到B树,红黑树,hash表等......那么作为一种数据结构,就需要进行维护,保存。例如对u有MyISAM引擎来说,其索引相关的信息都会保存在 xxx.MYI当中进行保存与维护。而在InnoDB存储引擎当中,对应的表结构,数据以及索引都存储在了xxx.ibd当中

二 索引的优缺点

        优点:

                1. 索引的添加可以让我们通过这种数据结构快速的定位对应添加所以的数据,加快查询效率,并且降低数据库的IO次数。

                2. 通过索引将表当中的数据先进行排序,那么就会加快之后数据排序的效率,降低排序成本,降低CPU资源的消耗

        缺点:

                1. 前面我们提到,索引实际上是一种数据结构,那么索引列也是需要占用磁盘的一些空间的。消耗了额外空间(但实际上磁盘比较便宜,其所占用的空间也比较少,可以忽略不计)

                2. 索引提高了数据查询的效率,但是反过来,降低了对应数据的更新以及新增的效率。

这是因为索引也是一种数据结构,我们在修改对应数据的同时,对应的索引的数据也需要进行修改,由此造成的数据的新增和插入速度的降低(对于一些业务来说,实际上增删改占用的比例远远少于查询)

三 索引结构

        MYSQL的索引是在对应的存储引擎层实现的,不同的存储引擎对应的有不同的索引结构,索引结构主要包含以下几种:

        B+Tree索引:最常见的索引类型,大部分的索引引擎都支持

        Hash索引:底层通过HASH表实现,因此决定了其只能够进行精确匹配,无法进行范围查询

        R-tree(空间索引): 空间索引为MyISAM所特有的一种特殊的索引类型,主要用于地理空间数据类型

        Full-text(全文索引):是一种通过建立倒排索引,快速匹配文档的方式,类似于Lucene,ES等

   

倒排索引拓展:

                倒排索引实际上也是一种数据结构,广泛用于信息检索系统,例如搜索引擎。其基本思想是将文档中的   单词  与   包含这些单词的文档列表  进行映射,从而快速查找包含特定单词的文档。

                倒排索引组成部分:

                        词项(Term):文档中出现的唯一单词。

                        文档列表(Document List):包含该词项的所有文档的标识符。

                工作原理:                 

                        索引构建

                                在文档集合中提取所有的词项。

                                为每个词项创建一个列表,记录哪些文档包含该词项。

                        查询处理

                                当用户搜索某个词时,系统可以快速查找该词项对应的文档列表,而不需要逐个扫描所有文档。

四:B+Tree  索引结构

        首先让我们从简单的二叉树开始进行分析,通过其优缺点,观察,总结为什么大部分的存储引擎都选择这个作为索引结构

        1. 二叉树(特指BST)

                首先是二叉树,但是实际上我们这里指的是搜索二叉树(Binary Search Tree,BST),其主要特点是每个节点最多只能有两个子节点,每个节点的值都大于其左子树中所有节点的值,并且小于其右子树中所有节点的值。这种结构使得搜索、插入和删除操作都能在平均情况下以较高的效率进行。

                在常规情况下,所有的数据均匀分布且并不是太多的情况下,二叉树可以大大提高数据的查询效率。

                但是这种数据结构存在很大的弊端:

                1. 如果数据分布并不均匀,流入根节点为50,之后输入的几个节点全部都比50小,那么就会导致对应的数据全部都在左边,从而形成了一条链,那么我们要查询的节点的数据的效率可能就从原本的O(ln n)变为了O(n)的时间复杂度 。

                2. 如果对应的数据量比较多的情况下,因为每一个父节点下只能最多存储两个子节点信息,那么数据一旦变多,就会导致对应的层数加深,使得查询效率降低。

                解决办法:使用一种可以自动调节高度的树以解决问题1这种情况 == 》 红黑树

        2. 红黑树

                红黑树是搜索二叉树的升级版本,其会自动调节对应节点之间的高度,使得各个节点之间的高度之差的绝对值不大于1,从而避免那种类似‘链状’的存储情况发生。

                但是同样的,红黑树也会避免不了我们在搜索二叉树所指出的问题二,也就是避免不了因为存储的数据的数据量的激增而导致对应层数加深 - > 从而导致查询效率大大下降。

                那么有没有一种数据结构能解决这种层级过深所导致的问题呢?

                解决方法:使用B-tree 树结构

        3.B-tree(多路平衡查找树)

                从名字我们就可以知道,多路指的是其字节点的个数不再只能是2,而是由我们进行人为的指定,这样就会在一定程度上减少对应数据大量存储的时候所导致的层数过深的情况的产生。

                因此在B-Tree当中,我们需要指定对应的最大度数(max-degree),也就是对应一个节点的子节点个数。例如指定为5(5阶)的b-tree树,那么每一个节点最多可以存储4个KEY,以及5个指针信息。其一个节点下各个KEY的排列顺序也是从小到达进行排列。

                这里的5个指针分别指向的是5个范围之内的数据,以下图为例

                应当是:  小于20的数

                                大于20小于30的数

                                大于30小于40的数

                                大于40小于50的数

                                大于50的数 

                如上图当前节点已经存在了4个KEY,那么之后再进行存储就会将中间的数向上提取,之后将中间左边以及右边的数向两边搁置,我再添加一个KEY = 35

                那么加入之后当前节点的KEY当中,35是中间的数据,向上提。如图所示:

                而且还要注意的一点是,在B-Tree数当中,其所有节点既存放键(key) 也存放数据(data)

        4.B+Tree

               B+ 树是 B 树的一种变体。B 树和 B+树中的 B 是 Balanced (平衡)的意思。

               相比较于B-Tree,B+Tree与其有以下几点不同:

                        1>B 树的所有节点既存放键(key) 也存放数据(data),而 B+树只有叶子节点存放 key 和 data,其他内节点只存放 key。

                        2>B 树的叶子节点都是独立的;B+树的叶子节点有一条引用链指向与它相邻的叶子节点。

                B+树当中所有的元素都会出现在叶子节点当中,并且叶子节点之间的关系是一种链状排列,形成单向链表。

                 节点不再存放对应的KEY的值,而是仅仅只存放一个KEY,数据均放置在叶子节点当中,这样的设置就表明对应KEY其实就是一个索引,指向对应数据所在位置。

五 hash索引

        hash索引实际上背后是依据hash表构建的,存放方式是键值对的方式,其会将对应的KEY的值  ==> 通过一些效率比较高的哈希算法得到新的hash值 ==> 映射到对应的内存槽位上,然后将对应的数据存放在这个槽位上。

        但是多个数据的哈希值是可能重复的,也就是说通过KEY计算出来的hash值一样,这就叫做哈希冲突,发生哈希冲突时,哈希表使用链表的解决方式,也就是说即使当前的槽位上已经存在数据了,那么我也可以存放,我会将这个新的数据的值存放在此链表的末尾。但是这样也存在一定问题,聪明的你能想想为什么吗?告诉我吧 ^ - ^

        如图:

        这样就可以高效的通过KEY直接获取到对应的数据信息了

        但是哈希表的这种查找,存储数据的方式注定了其无法进行多条数据的查找,只能够做到一对一精确查找。否则就会降低查找效率。

六  思考题 - 为什么InnoDB选择B+Tree作为默认的索引结构?

        通过以上对于各个索引结构的分析,我们不难分析出为什么

        1. 相比较于BTS以及红黑树,B+树既能够避免链状结构的产生,从而导致查询效率的降低;也能够通过自定义最大度数来放置因为数据过多导致树的层级过深造成的查询速度变慢。因此,两者都OUT。

        2.相比较于B-Tree树来说,使用B+树仅仅只在叶子节点存放对应的KEY的数据,而B树在所有的子节点都存放有对应的VALUE,我们还知道索引这种数据结构是在存储引擎当中实现的,那么其存储则会跟随存储引擎存放在本地磁盘,而索引的存放空间是有限的,一个节点信息会存放在 ’一页‘ 上,‘一页’存储数据的大小为16K。而B树每一个子节点都会保存数据,就会导致一页种存储的键值减少,指针跟着减少,想要同样保存大量的数据,只能够增加树的高度,从而导致性能的下降,因此OUT。

        3. 相比于HASH,HASH虽然查询效率高,但是只能够进行精准匹配,无法进行范围性的查找,获取数据,因此OUT。

之后也会更新MYSQL相关内容,关注不迷路,兄弟们  ^ - ^

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

AI智能体Prompt预设词指令大全+GPTs应用使用

AI智能体使用指南 直接复制在AI工具助手中使用(提问前) 可前往SparkAi系统用户官网进行直接使用 SparkAI系统介绍文档:Docs 常见AI智能体GPTs应用大全在线使用 自定义添加制作AI智能体进行使用: 文章润色器 你是一位具有敏锐洞察…

el-tree树形结构拖拽层级错乱问题

背景: 项目中有个文件夹树形菜单,并且各级菜单中的子级元素是可以任意拖拽的,也就是树形结构拖拽修改分组。 问题分析: 出现拖拽层级错乱的问题,这通常意味着在进行节点拖拽操作后,树的层级关系没有正确地被维护。这可能是因为在更新节点位…

线程和进程(juc)

线程 一:概念辨析 1:线程与进程 进程: 1:程序由指令和数据组成,指令要执行,数据要读写,就需要将指令加载给cpu,把数据加载到内存,同时程序运行时还会使用磁盘&#x…

Java基础集合(Map)

存储特点 以键值对的形式存储, 一个元素由两个值组成 键(K-key): 无序, 无下标, 元素不可重复 值(V-value): 无序, 无下标, 元素可以重复 常用实现类 HashMap JDK1.2 底层哈希表实现 线程不安全, 效率高 LinkedHashMap JDK1.2 是HashMap的子类, 底层哈希表实现 线程不安全…

NEXT开发应用质量建议与测试指南

随着鸿蒙原生开发如火如荼的进展,NEXT对应用的质量提出了更高的要求。 NEXT的应用质量分为2个部分内容: ⚫ 体验质量: 功能数据完备、基础体验、HarmonyOS特征增强体验 ⚫ 内容合规: 资质、内容、广告、付费、开发者行为等 单元测…

java应用cpu占用过高故障排除

首先一定要清楚:java应用造成cpu过高的主要原因 1:一般是线程一直处于可运行(Runnable)状态,通常这些线程在执行无阻塞操作、循环、正则或纯粹的计算等任务 2:另一个可能造成CPU高的原因是频繁GC&#xff…

CPU是如何执行任务的?

你清楚下面这几个问题吗? 有了内存,为什么还需要 CPU Cache? CPU 是怎么读写数据的? 如何让 CPU 能读取数据更快一些? CPU 伪共享是如何发生的?又该如何避免? CPU 是如何调度任务的&#x…

最短路径算法(Dijkstra算法 + Bellman-Ford 算法 + Floyd-Warshall算法)

最短路径算法 完整版万字原文见史上最全详解图数据结构 1. Dijkstra算法(单源最短路径)(无负权边图) 算法原理 1. Dijkstra 算法通过 贪心策略 计算从一个源顶点到其他所有 顶点的最短路径。2. 时间复杂度为 O(V^2)&#xff08…

pyqt6事件概要

例子: 利用qtdesigner建立闹钟 python代码 # 导入所需要的文件 from PyQt6.QtGui import QIcon, QPixmap from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QListWidgetItem from PyQt6 import uic from PyQt6.QtCore import Qt, QTime imp…

位运算符I^~

&运算:上下相等才是1,有一个不同就是0 |运算:只要有1返回的就是1 ^(亦或)运算:上下不同是1,相同是0 ~运算:非运算,与数据全相反 cpu核心运算原理,四种cpu底层小电路 例&#xf…

【求助】Tinymce组件异常

版本号 { "tinymce/tinymce-vue": "^3.0.1", "tinymce": "^5.10.9", "vue": "^2.6.10", }问题: 就是红框处点击后没有菜单出现,下面是正常的

大模型分布式训练框架——DeepSpeed

本文的主要内容是阐述DeepSpeed训练模块在跟进大模型技术中的作用,重点解析了RLHF在其中的应用。文中深入探讨了模型训练的关键概念,如显存需求、优化器迭代和混合精度训练。针对大规模模型训练,介绍了模型并行和流水线并行等分布式训练方法&…

跟着AI 学 AI, 开发一个ChatBot, 完整图文版__持续更新中

跟着AI 学 AI, 开发一个ChatBot, 完整图文版__持续更新中.记录步骤以便排查错误。 使用Python 加 Visual Studio Code,开发代码。 使用Flask 套件和 ngrok 工具。 Step 1 下载安装Python ,下载完后 在CMD 测试 Python --version. 结果出现p…

Pyside6 --Qt Designer--Qt设计师--了解+运行ui_demo_1.py

目录 一、打开Qt设计师1.1 Terminal终端1.2 打开env,GUI虚拟环境下的scripts文件1.3 不常用文件介绍(Scripts下面) 二、了解Qt设计师的各个控件作用2.1 点击widget看看效果!2.2 点击Main Window看看效果 三、编写一个简易的UI代码…

『大模型笔记』OpenAI 十二天活动第1天:o1和o1 pro

『大模型笔记』OpenAI 十二天活动第1天:o1和o1 pro 文章目录 一. 『大模型笔记』OpenAI 十二天活动第1天:o1和o1 proOpenAI的12天活动o1完整版本的发布o1 Pro模式ChatGPT Proo1的性能提升多模态输入与推理o1 Pro模式的应用模型对话与历史问题示范二. 参考文献一. 『大模型笔记…

SpringBoot 运行发生异常:java: 错误: 不支持发行版本 5

一、异常: 二、原因: 本地运行用的是JDK17,报错应该是项目编译配置使用的Java版本不对,需要检查一下项目及环境使用的Java编译版本配置。 三、解决:

2024.12.2——[极客大挑战 2019]Secret File 1

知识点:抓包 代码审计 filter伪协议 一、解题步骤 step 1 查看源代码中的信息 查看源代码发现一个php文件:[./Archive_room.php](http://72df1f22-85bf-47bb-b23a-efcaf88701d4.node5.buuoj.cn:81/Archive_room.php) 点进去后发现没什么用&#xff0c…

MKS EDGE Series RF Generators Power Solution 软件

MKS EDGE Series RF Generators Power Solution 软件

【汇编语言】标志寄存器(一) —— 标志寄存器中的标志位:ZF、PF、SF、CF、OF 一网打尽

前言 📌 汇编语言是很多相关课程(如数据结构、操作系统、微机原理)的重要基础。但仅仅从课程的角度出发就太片面了,其实学习汇编语言可以深入理解计算机底层工作原理,提升代码效率,尤其在嵌入式系统和性能优…

【C++】priority_queue优先队列

大家好,我是苏貝,本篇博客带大家了解C的string类的priority_queue优先队列,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️ 目录 1. 介绍2. 仿函数(A) 介绍(B) 控制比较逻辑 3. priority_queue和…