初识mysql数据库之索引概念与磁盘效率问题

news2025/7/5 20:37:10

目录

一、索引的概念及作用

二、实际看看索引的效率提升

三、认识磁盘

1. 简单了解磁盘

2. 数据库文件存储位置

3. 定位扇区

4. 数据读取效率问题

5. 磁盘随机访问与磁盘连续访问

5.1 随机访问

5.2 连续访问

四、mysql与磁盘的交互

五、建立共识 


一、索引的概念及作用

索引,其实就是用于提高数据库的性能的。使用它不用加内存、不用改程序、不用调sql,只需要执行正确的“create index”,就可以让数据库的查询速度提高成百上千倍。

当然,数据库查询效率的提高也是有代价,那就是在插入、更新、删除的时候会增加大量的IO,拉低效率。因此,索引的价值仅仅体现在提高海量数据的检索速度上

常见的索引一般分为如下几种:
主键索引(primary key)唯一索引(unique)普通索引(index)全文索引(fulltext)

注意,mysql的服务器是在内存中的,因此,当mysql启动后,它会在内存中为我们开辟一块空间,当需要修改数据时,就会将磁盘中的数据加载到这块内存中,在内存中执行CURD操作,然后在合适的时间将内存中的数据刷新到外设中。索引也是如此。

大家知道,在实际中如果我们要提高搜索效率,其实就是对搜索的算法进行优化。对算法优化一般包含两个方面,一个是数据结构本身,例如将线性结构换成二叉树结构。第二种就是修改算法本身,即优化在特定数据结构下的查找方法,例如在线性表中不再线性遍历,而是二分查找。一般而言,数据结构改变,算法本身也需要跟着改变

对于索引而言也是如此。在索引中就是将数据存储到了特定的数据结构中,利用这个数据结构的优势提高搜索效率。因此,所谓的索引,其实就是在一个特定的数据结构中搜素数据

二、实际看看索引的效率提升

为了方便看到索引带来的效果,所以我们需要准备一份非常大的数据进行索引。

在这里准备了这样的一张表,然后向里面插入800w行数据。如果大家也想在自己的机器上实际看到索引的效果,可以到网上直接搜索存储大量数据的数据表,有现成的代码,大家直接复制就可以向特定表中插入大量的数据。

注意,当插入成百上千万行数据时,根据你的配置,插入需要的时间可能不同,配置好的话可能几分钟,配置差点可能就要10几分钟乃至更高。大家看到mysql一直下面的插入状态的话,不要去结束它。

还有一个点,在你复制的代码中检查一下数据表的创建里面有没有带上主键、唯一键等属性,如果有,将它去除掉,以方便看到一份“没有索引”的表的搜索效率

当数据插入完成后,千万不要直接输入“select * from 数据表”查看数据表内容,因为里面的数据量非常大,如果直接用该命令而不带筛选选项,mysql就会不断显示数据。

有了这份存储有大量数据的表后,我们搜索一份数据:

可以看到,在这份存储有800w行数据的表内查询一个数据,花费了5.65s。很明显,这是不能接受的。要知道,一个公司的数据库中有个几百上千万行数据是非常正常的,如果一个用户查询一条数据,数据库要用5s才能返回数据,很明显是用户所不能接受。并且这仅仅是一个用户查,如果是成百上千乃至更多用户同时查数据,那么数据库的响应速度会更慢,甚至直接挂掉。

由此,我们就必须要想办法提高数据库中数据的查询效率。

输入“alter table 数据库名 add index(列名)”,指定一列为其添加索引。

索引添加完后,我们再到数据库中查询同一份数据:

可以看到,当我们为表添加索引后再去表中搜索数据,它的搜索时间就变为了0s。几乎就是在一瞬间就搜索完成了。通过这个例子,就可以明显的看到索引带来的查询效率提升。

三、认识磁盘

1. 简单了解磁盘

我们知道,一般来讲,数据都是存储在磁盘中的。因此,mysql作为一个给用户提供数据存储服务的服务端,它也是将用户数据存储到磁盘这个外设中的。但我们知道,磁盘作为计算机中的一个机械设备,相比与计算机中的其他电子元件,磁盘的存储效率是比较低的。再加上数据IO本身还有一定的效率消耗,如何提升mysql的效率就是一个重要问题了。

由于本章的重点并不是研究硬件,并且在我以前关于linux的文章中也介绍过磁盘的结构了,这里就简要介绍一下。

一块普通的磁盘,它的物理结构如下所示:

在这里面的圆盘,就是盘片,上面是有起伏的,每个起伏就代表着二进制,我们的数据就是存储在这块盘片中的。在盘片的上下有一个磁头,它会左右来回摆动,磁头的作用就是读取盘片中保存的二进制数据。在盘片的中间有一个主轴,这个主轴中有一个马达,用于让盘片高速旋转。

注意,磁盘上的盘片是一摞,而不是一片。在这些盘片的上下两面都可以存储数据,这就意味着每一面都有一个磁头在来回摆动读取数据

在盘片中,磁盘表面被分为许多个同心圆每个同心圆都称为一个磁道每个磁道都有一个编号最外面的就是0号磁道

每个磁道又被划分为若干段(段又叫扇区)每个扇区的存储容量都是相同的,一般为512字节,每个扇区都有一个编号。但是随着磁盘的发展,现在的扇区正在逐渐扩大,已经出现了更高效的4096字节扇区,被称为“4K扇区”。当然,因为我们不是专门研究磁盘的,不必太过关心,有个大致了解即可。

注意,虽然磁盘上每个扇区的实际大小有差距,但是上面的存储容量都是一样的,因为每个扇区的存储数据量不是看扇区大小,而是看数据存储密度。虽然上文中说磁盘上每个扇区的大小是一样的,但这并不绝对,随着磁盘的发展,已经慢慢出现了扇区容量不一样的磁盘了。在这里暂时不做考虑。

2. 数据库文件存储位置

在数据库中的数据库文件,无论是数据库,还是表,还是表中的数据,其本质都是被保存在磁盘的盘片中的一个个扇区内的。当然,由于一个扇区的存储容量很小,所以当数据库文件很大是,就需要占据多个扇区。

就算是我们当前使用的linux中所看到的大部分目录或文件,其实也是保存在硬盘中的。(注意,有一些内存文件系统,如porc、sys等,我们不做考虑)。

由此,找到一个文件,本质就是在磁盘上找到保存该文件的扇区。这也就要求磁盘要有能够定位任意一个扇区的能力

3. 定位扇区

上图是一张有三个磁盘六个盘面的磁盘。在这个磁盘中,每一面都有一个对应的磁头用于读取数据。当我们需要查找某份数据时,就是先确定它在哪一面,找到数据所处的盘面后,再找到它所在磁道, 然后找到数据在该磁道上的哪一个扇区。当找到数据所在扇区后,就可以通过磁头读取数据

由此,我们只需要知道磁头、柱面(等价于磁道)、扇区对应的编号,就可以在磁盘上定位所要访问的扇区,这种磁盘数据定位方式叫做CHS。不过实际系统软件中使用的不是CHS,而是LBA,是一种线性地址,大家可以LBA和CHS分别想象为虚拟地址和物理地址。系统会将LBA地址转化为CHS,交给磁盘去进行数据读取。

4. 数据读取效率问题

通过上面的内容大家应该就知道磁盘是可以定义任意一个扇区的。但是,在系统层面上来看,难道系统软件就是直接按一个扇区(512字节或4096字节)进行IO交互的吗?其实并不是。

这里存在几个原因。

(1)如果OS直接使用硬件提供的数据大小进行交互,这就意味着系统的IO代码和硬件强相关,当硬件发生变化时,系统的IO也就必须跟着变化。

(2)从实际来看,以512字节进行IO还是太小了。IO单位过小,就意味着读取同样的数据内容,需要进行更多的磁盘访问,会带来效率的降低。

(3)大家应该了解过文件系统,文件系统中读取数据的基本单位就不是扇区,而是数据块。一个数据块的大小是4KB。

因此,系统读取磁盘时,并不是以扇区为单位,而是以数据块为单位,基本单位是4KB

至于为什么一个数据块是4KB,一个方面是内存管理的问题。磁盘数据是需要加载到内存中的,而内存中本身就是以4KB划分成多个数据块的,因此,以数据块为基本单位与磁盘交互,更有利于磁盘与内存的IO交互。

另一个理由就是效率问题。在磁盘读取中,就算系统只需要1字节的数据,也需要从磁盘中读取4KB,有人可能认为这是一种浪费,但是这是从效率上考虑过的。因为系统读取数据时,它读取的数据大概率都是存放在一起的,而一次性读取4KB数据,就可以做到数据的预加载,当系统再次读取数据时,它读取的数据大概率就是已经提前加载好的数据,以此减少系统与磁盘的IO次数,提高数据的读取效率。

5. 磁盘随机访问与磁盘连续访问

5.1 随机访问

随机访问,是指本次IO所给出的扇区地址和上次IO给出的扇区地址不连续,这样的话磁头在两次IO操作之间需要作比较大的移动动作才能重新开始读写数据。

5.2 连续访问

如果当次IO给出的扇区地址与上次IO结束的扇区地址是连续的,那磁头就能够很快的开始这次IO操作。这样的多个IO操作称为连续访问。

注意,哪怕相邻的两次IO操作在同一时刻发出,但如果它们的请求的扇区地址相差很大的话,也只能称为随机访问,而非连续访问。

因为连续访问的效率要比随机访问高,所以大家涉及IO的程序中,尽量还是要体现出连续访问,而非随机访问。但是要注意,磁盘的效率问题并不是这么简单就能够解决的,磁盘中也是有很多方案设计用于提高效率的。这里只是简单介绍一下。

四、mysql与磁盘的交互

mysql作为一个应用软件,可以想象为一种特殊的文件系统。它有着更高的IO需求。因此,为了提高基本的IO效率,mysql进行IO的基本单位是16KB

这也就意味着,虽然磁盘的基本单位是512字节,但是MYSQL中的InnoDB引擎使用16KB进行IO交互。即mysql和磁盘进行数据交互的基本单位是16KB。这个基本数据单元,在mysql中叫做“page”(注意,这个page和系统的page不同,要将两者区分开来)。

但是大家知道,在OS中,应用软件是无法直接与外设交互的,必须通过OS。因此,当mysql要与磁盘IO时,并不是双方直接交互,而是OS从磁盘中读取4个数据块,即16KB的数据放到文件系统的文件缓冲区内,而在文件系统中的一个文件缓冲区,其实就可以看成是文件系统打开的一个文件,这个文件会返回一个文件描述符给mysql,让mysql用这个文件描述符读取数据。当然,这并不准确。在mysql中也是存在一个自己的“buffer pool”的,大家可以将其看做一个存储数据的空间。mysql所有的CURD操作都是在这个buffer pool中完成的。

至于mysql中写入的数据,就是交给OS,然后OS在满足一定条件后将数据刷新到磁盘上即可。通过这种方式,就提高了mysql的IO效率。

大家也可以在自己的linux中的mysql下输入“show global status like 'innodb_page_size';”命令查看使用InnoDB引擎的mysql下的page大小:

可以看到,大小为16384,单位是字节,换算过来就是16KB。

五、建立共识 

 通过上面的内容,我们就需要建立以下几个共识:

(1)mysql中的数据文件,是以page为单位保存在磁盘当中的。

(2)mysql的CURD操作,都需要通过计算找到对应的插入位置,或者找到对应要修或查询的数据

(3)在计算机中只要涉及到计算,就需要CPU参与,而为了方便CPU参与,就需要将数据移动到内存中

(4)因为要将数据移动到内存中,这就意味着在特定时间段内,数据一定是磁盘和内存中都有的。后续操作完内存数据之后,就需要以特定的刷新策略将数据刷新到磁盘中。此时,就涉及到磁盘和内存的数据交互,也就是IO了。而mysql中IO的基本单位就是page。

(5)为了能够更好的进行上面的操作,mysql服务器在内存中运行的时候,在服务器内部就申请了被称为“buffer pool”的大内存空间,这个空间默认为128MB,用于和磁盘数据进行IO交互。

(6)为了提高效率,一定要尽可能的减少系统和磁盘IO的次数。

上文中说mysql中有一个buffer pool内存空间,我们可以输入“vim /etc/my.cnf”打开数据库配置文件查看:

可以看到,配置文件中有这么一条注释,将这条指令放开,我们就可以修改buffer pool的大小。不放开的话大小默认为128MB。

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

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

相关文章

讯为RK3568开发板到手编译buildroot系统入坑一

从事单片机开发多年一直想买一个开发板学习Linux系统,这次狠心花了800多打样买了一个讯为的RK3568低配。裸板配置。 因为讯为没有编译系统的视频教程,只有文档的教程,而且只有瑞芯微官方带的Linux源码中的系统编译后文档教程。像ubuntu是没有…

网络编程Java Socket(UDP/TCP 套接字)

Socket是什么? 想知道Socket是什么就先得了解一下什么是网络编程 网络编程,通过代码来控制两个主机的进程之间能够进行数据交互。 操作系统就把网络编程的一些相关操作,封装起来了,提供了一组API供程序员使用。操作系统提供的功能…

Windows NT 驱动程序的编译、安装、调试

Windows NT 驱动程序的编译、安装、调试 Windows NT 驱动介绍NT 驱动代码分析编译安装修改注册表进行安装使用工具 DriverMonitor 进行打开加载安装 调试 Windows NT 驱动介绍 Windows 驱动分为两类,一类是从 Windows NT 遗留下来的驱动模型称为传统的 Windows NT …

1、Winform项目创建

项目创建的过程时比较简单的,要点在于选择基本库。 这里我们选择.Netframework 4.7.2,为什么使用这个呢?因为这个大多数windows系统上都装的有。如果使用.Net Core什么的,可能还需要再下载对应的运行库,影响用户体验。 具体步骤如下: 选择创建新项目 选择创建桌面应用…

RabbitMQ如何保证消息的可靠性6000字详解

RabbitMQ通过生产者、消费者以及MQ Broker达到了解耦的特点,实现了异步通讯等一些优点,但是在消息的传递中引入了MQ Broker必然会带来一些其他问题,比如如何保证消息在传输过程中可靠性(即不让数据丢失,发送一次消息就…

GDB调试基础知识

文章目录 概念准备工作常用命令说明启动与退出给程序设置参数/获取设置参数GDB使用帮助查看当前文件代码查看非当前文件代码查看及设置显示的行数断点操作调试操作 概念 GDB 是由 GNU 软件系统社区提供的调试工具,同 GCC 配套组成了一套完整的开发环境,…

Python基础教程——60个基础练习(三)

41-字符串格式化 "%s is %s years old" % (bob, 23) # 常用 "%s is %d years old" % (bob, 23) # 常用 "%s is %d years old" % (bob, 23.5) # %d 是整数 常用 "%s is %f years old" % (bob, 23.5) "%s is %5.2f…

ListBox基本用法

作用:列表框,用于以列表的形式展示数据。 常用属性: 允许多列显示数据 添加数据项集合 常用事件: 选择项变化时触发该事件 后台代码示范: //列表框项目选择变化时被触发private void listBox1_SelectedIndexChanged…

Flutter 跳转应用市场评分——超简洁实现

最近在做flutter跳转去应用市场评分的功能,虽然是一个很小的功能,但是要做的既简单又高效,同时又能把细节考虑到,还是有坑要走的,这边记录一下。 背景 做应用市场相关的运营,在app内增加评分引导&#xf…

经典目标检测R-CNN系列(1)开山之作R-CNN

经典目标检测R-CNN系列(1)开山之作R-CNN 2014年,大神RBG(Ross Girshick)等人将卷积神经网络(Convolutional Neural Network,CNN)应用于目标检测任务中,在PASCAL VOC 2012数据集上,能…

vue 如何发布并部署到服务器

一般情况npm run build即可 从而生成vue代码直接放到服务器即可 这里的具体情况要看package.json里面的配置从而使用命令 会生成dist就是该项目的发布包

软件测试项目经验重要吗?

目前从行业薪资排名看,IT行业是我们普通人能够接触到的高薪行业,像金融、银行和投行等高薪职位,张雪峰老师在他的视频中分析过,不是一般人可以拿捏的。IT行业的大部分岗位需要专业的技能,留给我们这些非计算机专业科班…

实现微信机器人开发,个微api

首先微信聊天机器人,是一种通过自然语言模拟人类进行对话的程序。通常运行在特定的软件平台上,如PC平台或者移动终端设备平台。 有兴趣的可以去进行测试(E云管家),功能十分全面 文档测试过程中实现多项功能进行管理 …

数据结构--线性表的链式存储结构

这里写目录标题 链式存储结构链表简介格式分类头结点位置示意图与不带头结点的区别 链表的特点 单链表定义链表的代码实现简介实操 基本操作的实现初始化单链表销毁单链表清空单链表求单链表表长 二级目录二级目录二级目录二级目录二级目录二级目录 链式存储结构 链表 简介 格…

QML学习day1

QML学习day1 main.qml import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.5Window {width: 640height: 480visible: truecolor:"blue"title: qsTr("Hello World")Button {//按钮id: btn1width: 50height: 50focus: true //聚焦…

P106-100组A卡(R5 240)指南

P106-100组A卡(R5 240)指南 不建议小白尝试 不建议小白尝试 不建议小白尝试文章目录 P106-100组A卡(R5 240)指南资料合集硬件软件基础卸载所有原驱动安装驱动修改注册表自动调用——只改一个注册表手动调用——改两个注册表 劝退…

软件设计原则

在软件开发中,为了提高软件系统的可维护性和可复用性,增加软件的可扩展性和灵活性,程序员要尽量根据6条原则来开发程序,从而提高软件开发效率、节约软件开发成本和维护成本。 开闭原则 对扩展开放,对修改关闭。在程序…

Leecode402:移掉 K 位数字

这道题一看想的是可能用回溯或者什么别的方法,但是那样的话时间复杂度非常高,而且也不适用于动态规划,所以观察的话,可以知道从前往后判断的话肯定是前面越小越好,所以只需要前面最小,整体就最小。因此从前…

子网掩码详解

1 子网掩码 IP地址是以网络号和主机号来标示网络上的主机的,我们把网络号相同的主机称之为本地网络,网络号不相同的主机称之为远程网络主机,本地网络中的主机可以直接相互通信;远程网络中的主机要相互通信必须通过本地网关&#…

酸蚀刻对钛医药材料纳米形态表面特性及活化能的影响

引言 由于商业纯钛(CP Ti)具有抗腐蚀性,并且具有哦合适的机械性能以及生物相容性,因此,目前一直被用作牙科植入材料。为了在临床手术中获得高水平的成功,CP Ti的表面质量和形貌是影响植入手术结果的最关键因素之一,近…