【数据库】详解MySQL数据库中索引的本质与底层原理

news2025/1/24 19:04:45

目录

1.MySQL索引的本质

1.1.索引的重要性

1.2.索引演示

1.3.索引的底层原理

1.3.1磁盘IO的原理

1.3.2.硬盘的主要结构

1.3.3.工作情形

1.3.4.各主要部件说明

1.3.5.扇区中是如何表示01数据的

2.MySQL索引底层原理

2.1.二叉查找树

2.2.平衡二叉查找树

2.3.B树和B+树

3.MySQL索引如何存储数据

3.1.MySQL如何使用B+树

3.2.叶子节点可以存储多少数据

3.3.InnoDB引擎存储结构

3.4.MyISAM引擎存储结构


1.MySQL索引的本质

1.1.索引的重要性

从MySQL数据库中查找数据,就类似于从图书馆找书,如果书比较少,那么查找的速度会比较快,如果书比较多,那么查找的速度就会变慢。这个时候图书的分类管理就显得非常重要了,图书分类管理就类似于索引

1.2.索引演示

索引的本质是一种数据结构

假设MySQL中有这样一张表:emp表,表中有1000000

在没有索引的情况下执行select语句,执行速度相对较慢

SELECT * FROM emp WHERE ename = 'c999017';

可以对ename的列创建索引

--显示emp表所有的索引
SHOW INDEX FROM emp;
​
--对ename列创建索引
CREATE INDEX index_ename ON emp (ename);
​
--删除索引
DROP INDEX index_name ON emp

1.3.索引的底层原理

问:为什么在没有索引的情况下,查询速度会比较慢?

答:因为数据都是存储在磁盘上的,在执行SQL语句的时候,一定会从磁盘上读取相关的数据,这会产生磁盘IO。如果没有索引,那么会进行多次磁盘IO操作,比较耗时

1.3.1磁盘IO的原理

机械硬盘,由于信息载体为磁性物质,故又称磁盘

1.3.2.硬盘的主要结构

在硬盘盒里面有圆形盘片、机械手臂、磁头、主轴马达

1.3.3.工作情形

数据写在具有磁性物质的盘片上,而读写主要是通过在机械手臂上的磁头(head)达成

运行时,主轴马达让盘片转动,然后机械手臂可伸展让磁头在盘片上进行读写的动作

1.3.4.各主要部件说明

(1) 盘片和主马达

主马达就是一个电机,作用是让盘片转动起来

对于机械硬盘,最重要的结构是两面涂有磁性材料的盘片,在工作中会以每分钟7200转的速度旋转

盘片的作用是记录数据,在盘片上有序的排列了很多的小颗粒材料,它们都是磁性物质,可以被永久磁化和改变磁极,这两个磁极就分别表示了计算机二进制中的0和1

由于盘片是转动后读写数据的,所以,当初设计就是在类似盘片同心圆上面切出一个一个的小区块,这些小区块整合成一个圆形,让机器手臂上的磁头去存取。这个小区块就是磁盘的最小物理储存单位,称之为扇区(sector),那同一个同心圆的扇区组合成的圆就是所谓的磁道(track)

扇区容量:原本硬盘的扇区都是设计成 512Byte(即0.5KB) 的容量,但因为近期以来硬盘的容量越来越大,为了减少数据量的拆解,所以新的大容量硬盘已经有 4KByte(即4KB)的扇区设计

由于单一盘片的容量有限,因此有的硬盘内部会有两个以上的盘片

由于磁盘里面可能会有多个盘片,因此在所有盘片上面的同一个磁道可以组合成所谓的柱面 (cylinder)

数据存储在盘片的一个个扇区中

  • 一个扇区可存储512Byte的数据

  • 一个平面中同一半径下的多个扇区共同组成了一个磁道

  • 一个盘片有两个盘面,每个盘面都对应着一个磁头,负责读写数据

  • 一个硬盘可以有多个盘片

  • 同一半径下的多个磁道共同组成了一个柱面

(2) 磁头和机械手臂

机械手臂的作用是控制磁头移动

磁头的作用是在盘片上读写数据。磁头通过改变盘片上小颗粒磁性物质的磁极方向来完成写入数据的功能,通过感知盘片上磁性物质的磁极方向来完成读取数据的功能

1.3.5.扇区中是如何表示01数据的

硬盘是在硬质盘片(一般是铝合金,以前 IBM 也尝试过使用玻璃)上涂敷薄薄的一层铁磁性材料。这些磁粉被划分成磁道的若干个同心圆,在每个同心圆的磁道上就好像有无数的任意排列的小磁铁,它们分别代表着0和1的状态。当这些小磁铁受到来自磁头的磁力影响时,其排列的方向会随之改变。利用磁头的磁力控制一些小磁铁方向,使每个小磁铁都可以用来储存信息

写入时,磁头线圈上加电,在周围产生磁场,磁化其下的磁性材料;电流的方向不同,所以磁场的方向也不同,可以表示0和1的区别

读取时,磁头线圈切割磁场线产生感应电流,磁性材料的磁场方向不同,所以产生的感应电流方向也不同

当需要从磁盘读取数据的时候,操作系统会将数据逻辑地址传给磁盘,磁盘的控制电路按照寻址逻辑将逻辑地址翻译成物理地址,即确定要读的数据在哪个磁道,哪个扇区。为了读取这个扇区的数据,需要讲磁头放到这个扇区的上方。为了实现这一点,磁头需要移动对准相应的磁道。这个过程叫寻道,所消耗的时间叫做寻道时间。然后磁盘旋转将目标扇区旋转到磁头下,这个过程消耗的时间叫做旋转时间

2.MySQL索引底层原理

2.1.二叉查找树

树形结构网站:

Data Structure Visualization

采用二叉树作为索引的数据结构时,特点是:左子节点的值比父节点的值要小,右节点的值要比父节点的大

优点:可以优化磁盘IO的次数。节点有顺序,可以进行范围的查询

缺点:插入数据的速度会比较慢,因为会更改数据结构。可能会产生倾斜的二叉树

2.2.平衡二叉查找树

插入数据会平衡,但是插入的时候会改变树的结构,插入数据比较慢,而且树的层级会变高,会增加磁盘IO的次数

二叉树是有顺序的,支持范围查找

2.3.B树和B+树

B树

B+树

B树或者B+树的节点可以存储多个数据,所以相对于完全平衡二叉树的高度会更低,会降低磁盘IO的次数

B+树相对于B树有数据的冗余,叶子结点中的数据是有顺序的,那么再进行顺序查找的时候会非常方便,只要在叶子结点顺序向后遍历即可

3.MySQL索引如何存储数据

3.1.MySQL如何使用B+树

MySQL中InnoDB和MyISAM存储引擎默认使用B+树数据结构作为索引,存储的数据结构如下

问:为什么只有叶子结点会存储数据,而非叶子结点不存储数据

答:局部性原理:当一个数据被用到时,其附近的数据被用到的概率会增大,所以操作系统为了提高效率,读取数据时往往不是按需读取,而是每次都会预读,即使只需要一个字节,操作系统也会从这个位置开始,顺序向后读取一定长度的数据放入内存中。这里的长度叫做页,也就是计算机操作系统操作磁盘的基本单位,一般操作系统中一页的大小为4kb

在MySQL中可以使用如下的命令查看InnoDB引擎页的默认大小

SHOW GLOBAL STATUS LIKE 'Innodb_page_size'

MySQL页的大小默认是16kb,B+树的设计非常适合读取数据

如果节点既存储数据又存储索引,一个节点的大小一定,数据较多时索引就较少,每个节点的分支会变少,树的高度会变高,导致磁盘IO变多,效率变低

3.2.叶子节点可以存储多少数据

一个节点可以存储16kb的数据,这是MySQL默认的节点大小:一页16kb

假设一行记录的大小为1kb(其实已经很大了)

那么一个叶子节点就能存储16条数据

非叶子节点里面存储的是索引的值和指针,MySQL默认的索引值大小是8B,指针大小是6B,合在一起是14B,那么非叶子节点可以存储的索引+指针的个数为:

16 * 1024 / 14 = 1170个

如果树的高度是2层,叶子节点的个数是1170个,那么可以存储的数据条数就是:

1170 * 16 = 18720条

如果树的高度是3层,那么叶子节点可以存储的数据条数就是

1170 * 1170 * 16 = 21902400条

3.3.InnoDB引擎存储结构

数据文件

user.frm是创建表的文件

user.ibd是数据+索引文件

InnoDB引擎是聚集索引,索引和数据文件在一起

如果以name字段设置索引,那就是二级索引(辅助索引)。叶子结点中存储该列的数据和主键值,也就意味着还需要再通过主键去查找一次数据

3.4.MyISAM引擎存储结构

MyISAM引擎的索引采用的非聚集索引,索引和表数据分开存储

user.frm文件是创建表的文件

user.MYD文件是表的数据文件

user.MYI文件是索引文件

索引文件:

数据文件:

MyISAM引擎通过索引值找到对应的地址,通过地址找到数据

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

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

相关文章

网络编程原理:回显服务器与客户端通信交互功能

文章目录 路由器及网络概念网络通信基础TCP/IP 五层协议封装和分用封装分用 网络编程(网络协议)UDP类 API使用实现回显通信程序回显服务器(UDP代码)回显客户端(UDP代码) TCP API使用回显服务器(TCP代码)回显客户端(TCP代码) 路由器及网络概念 网络发展是…

AIGC视频扩散模型新星:Video 版本的SD模型

大家好,这里是好评笔记,公主号:Goodnote,专栏文章私信限时Free。本文详细介绍慕尼黑大学携手 NVIDIA 等共同推出视频生成模型 Video LDMs。NVIDIA 在 AI 领域的卓越成就家喻户晓,而慕尼黑大学同样不容小觑,…

[Day 15]54.螺旋矩阵(简单易懂 有画图)

今天我们来看这道螺旋矩阵,和昨天发的题很类似。没有技巧,全是循环。小白也能懂~ 力扣54.螺旋矩阵 题目描述: 给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。 示例 1: …

用Python绘制一只懒羊羊

目录 一、准备工作 二、Turtle库简介 三、绘制懒羊羊的步骤 1. 导入Turtle库并设置画布 2. 绘制头部 3. 绘制眼睛 4. 绘制嘴巴 5. 绘制身体 6. 绘制四肢 7. 完成绘制 五、运行代码与结果展示 六、总结 在这个趣味盎然的技术实践中,我们将使用Python和Turtle图形…

QT QTreeWidget控件 全面详解

本系列文章全面的介绍了QT中的57种控件的使用方法以及示例,包括 Button(PushButton、toolButton、radioButton、checkBox、commandLinkButton、buttonBox)、Layouts(verticalLayout、horizontalLayout、gridLayout、formLayout)、Spacers(verticalSpacer、horizontalSpacer)、…

掌握Spring事务隔离级别,提升并发处理能力

Spring框架支持的事务隔离级别与标准的JDBC隔离级别保持一致,共包括五大隔离级别,它们分别是:DEFAULT(默认隔离级别)、READ_UNCOMMITTED(读未提交)、READ_COMMITTED(读已提交&#x…

Vue基础(2)

19、组件之间传递数据 组件与组件之间不是完全独立的&#xff0c;而是有交集的&#xff0c;那就是组件与组 件之间是可以传递数据的 传递数据的解决方案就是 props ComponentA.vue <template><!-- 使用ComponentB组件&#xff0c;并传递title属性 --><h3>…

Git知识分享

一、理解git首先要理清楚下面五个概念&#xff1a; 1、工作区(git add 命令之前的样子) 2、stash 暂存(暂存工作区和暂存区的更改) 3、暂存区(git add 命令之后的存储区, 4、本地仓库(git commit提交的位置) 5、远程仓库(git push提交的位置) 二、git常用命令&#xff1a; 1、g…

【2024 - 年终总结】叶子增长,期待花开

写在前面&#xff1a;本博客仅作记录学习之用&#xff0c;部分图片来自网络&#xff0c;如需引用请注明出处&#xff0c;同时如有侵犯您的权益&#xff0c;请联系删除&#xff01; 文章目录 前言论博客创作保持2024的记录清单博客科研开源工作生活 总结与展望互动致谢参考 前言…

分类问题(二元,多元逻辑回归,费歇尔判别分析)spss实操

分类模型&#xff1a; 二分类和多分类&#xff1a; 对于二分类模型 &#xff0c;我们将介绍逻辑回归和Fisher线性判别分析两种分类算法; 对于多分类模型&#xff0c;我们将简单介绍Spss中的多分类线性判别分析和多分类逻辑回归的操作步骤 二分类: 基于广义线性模型&#x…

k8s使用nfs持久卷

开启持久化卷后可以实现服务开启在不同节点也能读取到和拿到服务节点的文件。 基本流程为将集群中一个节点作为服务节点安装共享储存应用的服务端选择目录和开启端口&#xff0c;其他节点根据端口挂载目录。然后使用kubesphere选择相应的镜像并将端口信息和挂载目录信息作为参…

kalman滤波器C++设计仿真案例

很多同学看了我之前的文章&#xff0c;都对kalman滤波器的原理有了理解&#xff0c;但我发现&#xff0c;在具体工程设计过程中&#xff0c;还是很多人都感觉到无从下手&#xff0c;一些参数也不知道如何选取。 这样吧。我这里举一些简单的例子&#xff0c;并用C来一步一步的进…

2025.1.21——六、BUU XSS COURSE 1 XSS漏洞|XSS平台搭建

题目来源&#xff1a;buuctf BUU XSS COURSE 1 目录 一、打开靶机&#xff0c;整理信息 二、解题思路 step 1&#xff1a;输入框尝试一下 step 2&#xff1a;开始xss注入 step 3&#xff1a;搭建平台 step 4&#xff1a;利用管理员cookie访问地址 三、小结 二编&#…

微信小程序使用上拉加载onReachBottom。页面拖不动。一直无法触发上拉的事件。

1&#xff0c;可能是原因是你使用了scroll-view的标签&#xff0c;用onReachBottom触发加载事件。这两个是有冲突的。没办法一起使用。如果页面的样式是滚动的是无法去触发页面的onReachBottom的函数的。因此&#xff0c;你使用overflow:auto.来使用页面的某些元素滚动&#xf…

Linux-arm(1)ATF启动流程

Linux-arm(1)ATF启动流量 Author&#xff1a;Once Day Date&#xff1a;2025年1月22日 漫漫长路有人对你微笑过嘛… 全系列文章可查看专栏: Linux实践记录_Once_day的博客-CSDN博客 参考文档&#xff1a; ARM Trusted Firmware分析——启动、PSCI、OP-TEE接口 Arnold Lu 博…

docker 部署 java 项目详解

在平常的开发工作中&#xff0c;我们经常需要部署项目&#xff0c;开发测试完成后&#xff0c;最关键的一步就是部署。今天我们以若依项目为例&#xff0c;总结下部署项目的整体流程。简单来说&#xff0c;第一步&#xff1a;安装项目所需的中间件&#xff1b;第二步&#xff1…

ARM64平台Flutter环境搭建

ARM64平台Flutter环境搭建 Flutter简介问题背景搭建步骤1. 安装ARM64 Android Studio2. 安装Oracle的JDK3. 安装 Dart和 Flutter 开发插件4. 安装 Android SDK5. 安装 Flutter SDK6. 同意 Android 条款7. 运行 Flutter 示例项目8. 修正 aapt2 报错9. 修正 CMake 报错10. 修正 N…

MySQL5.7安装超详细步骤(图文教程)

一.下载MySQL 1.在浏览器搜索MySQL&#xff0c;进入MySQL官网&#xff0c;点击下载&#xff0c;选下面的社区版本。 官网地址&#xff1a;MySQL :: Download MySQL Installer (Archived Versions) 二.安装MySQL 1.双击下载好的文件&#xff0c;选择自定义安装&#xff0c;然…

Tomcat下载配置

目录 Win下载安装 Mac下载安装配置 Win 下载 直接从官网下载https://tomcat.apache.org/download-10.cgi 在圈住的位置点击下载自己想要的版本 根据自己电脑下载64位或32位zip版本 安装 Tomcat是绿色版,直接解压到自己想放的位置即可 Mac 下载 官网 https://tomcat.ap…

语音转文字的先驱-认识Buzz的前世今生

Buzz 是一款基于 OpenAI Whisper 模型开发的开源语音转文字工具&#xff0c;其历史可以追溯到 Whisper 模型的推出&#xff0c;并在之后逐渐发展为一个功能强大且广泛使用的工具。以下是关于 Buzz 的详细历史介绍&#xff1a; 1. Whisper 模型的背景 Buzz 的核心是 OpenAI 开…