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

目录

一、索引的概念及作用

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

三、认识磁盘

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。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flask_使用flask_marshmallow序列化数据

代码如下: from flask import Flask from flask_marshmallow import Marshmallow from flask_sqlalchemy import SQLAlchemy from marshmallow import fieldsapp Flask(__name__) app.config["SQLALCHEMY_DATABASE_URI"] "mysqlpymysql://root:12…

excel常用操作备忘

excel操作: 1、快速填充多列公式:选中多列后,按ctrlD填 充。 2、快速删除空行:全选行,按ctrlG,空值项前边打上钩,点确定,针对选中的空行,鼠标右击,点删除&…

消息推送(websocket)集群化解决方案

目录 需求分析解决方案实现步骤架构图配置websocket请求地址配置websocket连接前置和连接关闭监听配置websocket处理程序配置redis交换机配置redis订阅监听配置redis发布监听需求分析 及时信息传递:消息推送功能能够确保网站向用户发送及时的重要信息,包括新闻更新、促销活动…

漏洞复现畅捷通CRM SQL注入

免责声明 术文章仅供参考,任何个人和组织使用网络应当遵守宪法法律,遵守公共秩序,尊重社会公德,不得利用网络从事危害国家安全、荣誉和利益,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失,均由使用…

网络安全专业必考的三个证书,初学者建议收藏!

学习网络安全,有三个必考证书,最后一个人手一本! 一,NISP证书 NISP即国家信息安全水平考试,由中国信息安全测评中心发证,属于网络安全专业的必考证书。 只有考取NISP一级证书才有机会考取二级&#xff0…

三季度上市,比亚迪海豹DM-i内饰官图发布,延续海洋风格

据报道,比亚迪海洋网旗下全新车型海豹 DM-i今日发布了内饰官方图片。新车内部采用了独特的“海洋美学”设计理念,并体现了海洋网最新一代内饰风格。消息称,这款车型将于第三季度上市,定位为中大型混合动力轿车。 值得注意的是&…

亚马逊会员日结束了,如何防止销量和排名“断崖式”下跌?

令人瞩目的2023亚马逊Prime会员日落下了帷幕,据官方数据显示,48小时售出商品超3.75亿件,再一次创造了历史新纪录! 好不容易因为亚马逊会员日提升了销售额和曝光了品牌,那么会员日结束了,如何稳住您的销量和…

java通过url获取视频时长(无需下载文件)

1、导入架包 <!-- jave 核心依赖 --><dependency><groupId>ws.schild</groupId><artifactId>jave-core</artifactId><version>2.4.6</version></dependency><!-- 根据不同操作系统引入不同FFmpeg包 --><!-- wi…

【多线程例题】顺序打印abc线程

顺序打印-进阶版 方法一&#xff1a;三个线程竞争同一个锁&#xff0c;通过count判断是否打印 方法二&#xff1a;三个线程同时start&#xff0c;分别上锁&#xff0c;从a开始&#xff0c;打印后唤醒b 三个线程分别打印A&#xff0c;B&#xff0c;C 方法一&#xff1a;通过co…

keep-alive和router-view配合使用缓存整个路由页面以及路由切换

实现内容&#xff1a;通过vue实现&#xff0c;在页面有侧边栏动态来展示当前页面流程&#xff0c;右边进行页面的切换&#xff0c;左右两边都是组件&#xff0c;但是A/B/C组件的切换是通过keep-alive搭配router-view实现的&#xff0c;首先在当前文件中创建五个文件&#xff1a…

【搜索引擎Solr】Solr:提高批量索引的性能

几个月前&#xff0c;我致力于提高“完整”索引器的性能。我觉得这种改进足以分享这个故事。完整索引器是 Box 从头开始创建搜索索引的过程&#xff0c;从 hbase 表中读取我们所有的文档并将文档插入到 Solr 索引中。 我们根据 id 对索引文档进行分片&#xff0c;同样的文档 id…

云原生之深入解析Flink on k8s的运行模式与实战操作

一、概述 Flink 核心是一个流式的数据流执行引擎&#xff0c;并且能够基于同一个 Flink 运行时&#xff0c;提供支持流处理和批处理两种类型应用。其针对数据流的分布式计算提供了数据分布&#xff0c;数据通信及容错机制等功能。Flink 官网不同版本的文档flink on k8s 官方文…

优秀的 RocketMQ 可视化管理工具 GUI 客户端

优秀的 RocketMQ 可视化管理工具 GUI 客户端 官网地址&#xff1a;http://www.redisant.cn/rocketmq 快速查看所有 RocketMQ 集群&#xff0c;包括Brokers、Topics和Consumers查看消费者订阅了哪些主题&#xff0c;以及消息队列被分配给了哪些消费者&#xff1b;当出现消息积…

黑客(网络安全)自学

建议一&#xff1a;黑客七个等级 黑客&#xff0c;对很多人来说充满诱惑力。很多人可以发现这门领域如同任何一门领域&#xff0c;越深入越敬畏&#xff0c;知识如海洋&#xff0c;黑客也存在一些等级&#xff0c;参考知道创宇 CEO ic&#xff08;世界顶级黑客团队 0x557 成员…

(转载)极限学习机(extreme learning machine, ELM)的回归拟合及分类(matlab实现)

单隐含层前馈神经网络(single-hidden layer feedforward neural network,SLFN)以其良好的学习能力在许多领域中得到了广泛的应用。然而&#xff0c;传统的学习算法(如BP算法等)固有的一些缺点&#xff0c;成为制约其发展的主要瓶颈。前馈神经网络大多采用梯度下降方法&#xff…

MSA【1】:Segment Anything Model for Medical Image Analysis: an Experimental Study

文章目录 前言1. Abstraction & Introduction1.1. Abstraction1.2. Introduction1.2.1. What is SAM?1.2.2. How to segment medical images with SAM? 2. Methodology2.1. SAM is used in the process of segmentation of medical images2.1.1. Semi-automated annotati…

【golang中的切片的相关知识点】[ ] slice

golang-切片 切片的定义和初始化切片的内存分析切片的操作获取长度和容量追加元素复制切片 切片的遍历切片的特性总结 Golang中的切片是一种灵活且强大的数据结构&#xff0c;它可以动态地增长和缩小。切片是基于数组的抽象&#xff0c;它提供了更方便的操作和更灵活的内存管理…

前端实现 DIV 高度只有100px,宽度只有100px ,我要在这个DIV放一个宽度200的DIV,左右拉动滚动条显示

<!DOCTYPE html> <html> <head><title>点击监听两组span标签</title><style>.outer-div {width: 100px;height: 100px;overflow-x: scroll;background-color: #abc1ee;}.inner-div {width: 200px;}/* 自定义滚动条样式 */.outer-div::-web…

MYSQL多表查询

创建学生表和分数表并插入相应数据 mysql> INSERT INTO student VALUES( 901,张老大, 男,1985,计算机系, 北京市海淀区); mysql> INSERT INTO student VALUES( 902,张老二, 男,1986,中文系, 北京市昌平区); mysql> INSERT INTO student VALUES( 903,张三, 女,1990,中…

我是怎么把win11一步一步变成Mac的

目录 【三指拖动】 【空格预览】 【切换Ctrl和Alt】 【使用Linux命令】 【其它】 之前很长一段时间在MacBook上面开发习惯了&#xff0c;然后因为一些原因现在换到了windows上面&#xff0c;不管是使用上还是系统上都很不习惯&#xff0c;因此做了一些改造&#xff0c;…