IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> MySQL 索引底层原理 -> 正文阅读

[大数据]MySQL 索引底层原理

索引是帮助MySQL高效获取数据的排好序的数据结构。

索引是一种数据结构,数据结构有:二叉树(二叉查找树Binary Search Tree)、红黑树(Red Black Tree)、Hash表、B-Tree、B+Tree

索引详解:

1.假设索引采用二叉树数数据结构:

如图所示:我们建了一张表,一些个人数据,此时以age字段建一个索引,如果采用二叉树数据结构作为索引那么图如下:

此时如果进行查询:select * from user where age=29 ;

age为索引字段,会先去存储我们索引的数据页进行查询,29大于24,又小于31,很快找到29这个索引值,并且根据这个key值存储的磁盘文件地址值,再进行一次磁盘IO去查找这个地址存放的目标数据。如果age不是索引字段,则需要数据库一行一行数据去比对,比对6次以后才拿到目标数据,不停的进行磁盘IO,效率很低。

弊端:如果索引字段一直都是一种规律增加,树的高度会很高,而且查询效率依然很低,这种情况下,几乎变成了线性查找。如图:

2.红黑树?

此时红黑树就应运而生,可解决此问题,红黑树不仅具有二叉树的特性,还有自己的附加属性;

1.结点是红色或黑色。

2.根结点是黑色。

3.每个叶子结点都是黑色的空结点(NIL结点)。

4 每个红色结点的两个子结点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色结点)

5.从任一结点到其每个叶子的所有路径都包含相同数目的黑色结点。

?这里不做深入讲解(因为我也不是专家);这里解决问题的方式,就是利用红黑树的自旋的特性,如果出现线性的情况,红黑树的节点会进行左旋转或者又旋转,来达到树状结构的自我平衡

简单理解如图:

?旋转重新组成合理的树状结构,这样树的高度降低,查找的效率提高!例如主键:

? ? 在大数据量的情况下,红黑树依然会有性能问题,例如百万或者更多级别的数据,红黑树的高度依然会特别高,因为基本的特性就是二分查找。此时B-Tree就出现了,在纵向高度无法突破的情况下,只能考虑横向扩展,可考虑横向放的索引数据增加,让一个节点存放更多的索引元素,同时可以分更多的叉出来。

? ? 对红黑树进行一定的改造之后,就可以支撑大数据量的查找,高度可控制在5以内。

? ?B-Tree : 叶节点具有相同的深度 ,叶节点的指针为空,节点中的数据索引从左到右递增排列。

MySQL的索引底层用的?B+Tree ,是对B-Tree的一个改造,实际上是一个多叉平衡树。

B+Tree :?非叶子节点不存储data,只存储索引,可以放更多的索引;同时叶子节点维护了顺序访问指针(双向指针),提高区间访问的性能。(所有的索引元素都是存储在叶子节点里面,如下图示)

?

? ? ? 相关的索引数据只存储在叶子节点里面,这样做可以让非叶子节点能存储更多的索引,但也并不是说每一个节点索引可以无限存储,因为最后都是会放到内存里面去进行运算查找,需要考虑内存及成本。目前MySQL的每个节点分配的空间可以通过命令查看:

SHOW GLOBAL STATUS LIKE 'INNODB_page_size';

?每个节点分配了16384个字节,也就是16KB的空间。

?

?那么存储索引的时候,一个节点最多能存储 16k/14B=1170个索引;叶子节点由于存储了索引及相关的数据,叶子节点 假设每组大小为1KB则一个叶子节点可存16个数据;如图所示 ,B+Tree高度为3的时候,理论上所能存储的数据量则为:1170*1170*16=21902400 两千万的数据量。也就是千万级别的数据量情况下,树的高度只有3,效率很高。

? ? ? ?Hash表:MySQL目前支持BTREE 和 HASH 两种索引方法,也就是两种索引存储数据结构,用Hash散列算法,key为索引值,value为存储数据的磁盘指针数据,同hash算出来的值进行映射,这样进行单条数据查找的时候会非常快,但是一般数据库用的很少,虽然在进行单一数据查找很快,但是hash无法支撑范围查找,范围查找的时候性能会非常低,所支持的场景单一。

? ? ? ?B+Tree?叶子节点维护有指针,右边元素的索引值都是大于左边的,所以当出现范围查找的时候,只需要找到对应的索引即可找到想要的结果集。顺着指针依次将后面所有的元素放到结果集里面,如果没有这个指针,则会每次都要再从根节点开始去找对应的索引找数据。? ?


不同的存储引擎,底层用B+Tree存储的时候,存储文件还有一点点区别

1.MyISAM的索引文件和数据文件是分离的(非聚集)

? ? ?磁盘上文件存储的时候,一张表至少三个文件,*_myisam.frm 表结构文件,*_myisam.MYD 表数据行文件,*_myisam.MYI 存储表数据的索引(B+Tree结构)。如果是这种类型的存储引擎,命中索引的时候先去 MYI文件中定位到这个索引,找到这个文件中存储的对应的磁盘文件指针,此时(叶子节点的data存储的是这个索引所对应的数据所在磁盘的所在行的文件指针),再去MYD文件中找到对应的数据,放到内存中去。

2.InnoDB的索引实现(聚集),支持事务,用的最多

? ??表数据本身就是按B+Tree组织的一个索引结构文件,?聚集索引-叶子节点包含了完整的数据记录

? ? ?一张使用InnoDB存储引擎的表,对应的文件有两个*_innodb_lock_frm (表结构文件)、*_innodb_lock_ibd(存储了索引+数据),(叶子节点里面的data 存储的是相应的行数据),比MyISAM少了一次磁盘IO。

? ? ?为什么InnoDB必须有主键,且推荐使用整型自增主键?

? ? ?1.如果不设置主键依然可以建表存储,但是底层会自动识别一个字段或者单独建立一个字段作为主键。?

? ? 2.非主键索引,data存储的不是具体的行数据,而是主键索引

? ? 3.用整型是因为查找索引的时候会经过很多的比较运算操作,这种情况下其他类型效率不会很高,比如用UUID的时候,字符串进行比较,需要逐位对比,如果英文跟数字又需要转位ASCII码来比较大小,影响效率。

? ? 4.如果非自增主键,就会存在后续新增的数据可能在之前的节点的中间,由于data存储的行数据,一个节点16KB大小,如果本来这个叶子节点已经这么大了,现在又要新增一个主键索引和数据,之前的叶子节点就需要做一个数据页分裂操作,才能将新增的数据加进去,影响性能。用自增,则可以保证每次新增的数据都是在后面,不会遇到数据页分裂的情况。

? ? ?为什么非主键索引结构叶子节点存储的是主键值?(一致性和节省存储空间)

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-05-26 15:19:52  更:2022-05-26 15:20:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:48:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码