MySQL读取数据时发生了什么?数据读取过程分析[图]

上一篇咱们说到B+树拼接一己之力杀出重围,最后成为了InnoDB和MyISAM这两种存储引擎的索引实现。咱们都知道索引内心是有B+树的,他知道本身不可能所有存储在内存中,他通常是以「索引文件的形式存储的磁盘上」。那么MySQL读取数据时都发生了什么呢?这得从内存开始提及。
IRAM与ROM
ROM,Read-OnlyMemory:只读储存器,能够理解为电脑的硬盘上存放操做系统的软件,手机的内置储存上存放操做系统的软件,单片机的Flash上存放操做系统的软件。总之就是用来存储操做系统的软件。
RAM,Random-AccessMemory:随机储存器,能够理解为电脑的内存条。用于存放动态数据,也叫运行内存。系统运行的时候,须要把操做系统从ROM中读取出来,放在RAM中运行。
CPU要运行程序须要从ROM调取,但ROM又有距离,因此须要用RAM来作一个链接。
MySQL读取数据时发生了什么?数据读取过程分析[图]
I主存存储原理
RAM主要的做用就是存储代码和数据供CPU在须要的时候调用,可是这些数据并非像用碗盛饭那么简单,咱们是须要知道数据的特定位置信息。他更像是图书馆中用有格子的书架存放书籍同样,不但要放进去还要可以在须要的时候准确的调用出来,虽然都是书可是每本书是不一样的。对于RAM等存储器来讲也是同样的,虽然存储的都是表明0和1的代码,可是不一样的组合就是不一样的数据。
抽象地看,主存是一系列的存储单元组成的矩阵,每一个存储单元存储固定大小的数据。每一个存储单元有惟一的地址,现代主存的编址规则比较复杂,这里将其简化成一个二维地址:经过一个行地址和一个列地址能够惟必定位到一个存储单元。
I离主存读写工程
当系统须要读取主存时,则将地址信号放到地址总线上传给主存,主存读到地址信号后,解析信号并定位到指定存储单元,而后将此存储单元数据放到数据总线上,供其它部件读取。写主存的过程相似,系统将要写入单元地址和数据分别放在地址总线和数据总线上,主存读取两个总线的内容,作相应的写操做。
因此,主存存取的时间仅与存取次数呈线性关系,由于不存在机械操做,两次存取的数据的“距离”不会对时间有任何影响,例如,先取A0再取A3和先取B0再取C3的时间消耗是同样的。
I磁盘的构成
若是咱们将硬盘拆开,能够发现里面存在多张磁盘和多个读写磁头,加入一张磁盘有8张磁盘,就会有16个盘面和16个读写磁头了,全部的盘面构成了磁盘组合。
磁盘组合由一个或多个圆盘组成,他们围绕一根中心主轴旋转,圆盘的上下表面涂抹了一层磁性材料,二进制位被存储在这些磁性材料上。其中,0和1在磁材料中表现位不一样的模式。
盘片被划分红一系列同心环,圆心是盘片中心,每一个同心环叫作一个「磁道」,全部半径相同的磁道组成一个柱面。磁道被沿半径线划分红一个个小的段,每一个段叫作一个「扇区」,每一个扇区是磁盘的最小存储单元。为了简单起见,咱们下面假设磁盘只有一个盘片和一个磁头。
I随机读取
通常来讲,主存和磁盘以页为单位交换数据。在硬件及操做系统中,咱们每每将主存和磁盘存储区分割为连续的大小相等的块。每一个存储块称为一页(在许多操做系统中,页的大小一般为4k或者8k)。
I随机读取过程
在交换数据时,系统会将数据逻辑地址传给磁盘,磁盘的控制电路按照寻址逻辑将逻辑地址翻译成物理地址,即肯定要读的数据在哪一个磁道,哪一个扇区。为了读取这个扇区的数据,须要将磁头放到这个扇区上方。
I随机读取性能瓶颈
随机读取主要与性能瓶颈这三个指标有关:
1.磁头须要移动对准相应磁道的时间即寻道时间
2.磁盘旋转到指定磁道区域,即旋转延迟
3.从磁盘读出或将数据写入磁盘的时间,即传输时间。
通常来讲,主流磁盘寻道时间通常在5ms如下;旋转延迟也就是转速的通常(对于圆形来讲,最多走一半就能到对应区域),对于7200转的磁盘,旋转延迟应该在7200/3600/2=4.17ms。传输时间能够忽略不计,因此一次磁盘IO耗时应该在9ms之内。
其实9ms的随机读取其实已是一个灾难,好比一台常规的500-MIPS的机器每秒能够执行5亿条指令,也就是说一次随机读取的时间,机器能够执行5百万条指令,这个量级对比是惊人的。并且,对于一个百万级数据库查询的话,所花费的时间已经达到了9s,这个数据对于用户来讲实际上是一个难以容忍的数字了。
I局部性原理程序员

考虑到随机读取是高昂的消耗这个客观存在的事实,咱们计算机系统利用了局部性原理对磁盘进行顺序读取。书笔记做文网https://www.yuananren.com平常生活中,咱们都知道不少东西的分布都不是平均的,咱们更常见的几率分布实际上是正态分布。一个很形象的例子就是,大学中常常旷课的同窗,他的朋友也会常常旷课,他们造成了一个旷课圈。

磁盘每每不是严格按需读取,而是每次都会预读,即便只须要一个字节,磁盘也会从这个位置开始,顺序向后读取必定长度的数据放入内存。因此当一个数据被用到时,其附近的数据也一般会立刻被使用。程序运行期间所须要的数据一般比较集中。这就是咱们的局部性原理。
I顺序读取
磁盘顺序读取不须要寻道时间,只需不多的旋转时间。因此,咱们对于具备局部性的程序来讲,预读能够提升I/O效率。
I顺序读取过程
当程序要读取的数据不在主存中时,会触发一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,而后异常返回,程序继续运行。也就是咱们读取一页内的数据时候,实际上才发生了一次IO。
若是咱们须要将多个页读取到缓冲池中,并按顺序处理它们,此时读取的速度变的很快,此时读取每一个页所花费的时间大概为0.1ms左右,这个时间消耗对随机IO有很大的优点。
I顺序读取的条件
全表扫描
全索引扫描
索引片扫描
经过聚簇索引扫描表行
I离顺序读取的优点
节省开销。读取多页意味着平均读取每页性能增长。
预读。因为数据库引擎知道须要读取哪些页,全部能够在页被真正请求以前就提早将其读取进来。
IMySQL数据读取
MySQL数据的读取并非简单直接将内存与磁盘进行数据交换,而是使用缓冲池最小化磁盘活动。
每个缓冲池都足够大,大到能够存放许多页,多是成千上万的页。内存缓冲池和磁盘缓冲池遵循局部性原理,尽力确保常用的数据被保存于池中,以免一些没必要要的磁盘读。
根据主存存储原理,咱们能够很快在缓冲池找到一个索引或者表页。若是在缓冲池中,没有找到数据,会从磁盘服务器的缓冲区里面去读取。磁盘缓存池读取成本大概会在1ms左右。若是磁盘服务器的缓冲池中依然没有找到数据,此时就必需要从磁盘读取了。若是知足顺序读取的条件,那么就会尽快地顺序读取。若是不知足,那么就会可怕的随机读取。
I总结
本文主要阐述了MySQL数据读取的流程。认识到由于本身的小任性,须要查询一个值,MySQL这个暖男竟然鞍前马后干了这么多事情。甚至开始心疼软件工程师,软件工程师们想尽各类办法来作优化,性能提高倒是有限的。而硬件上的稍微有优化,性能提高倒是飞跃的。好比顺序读取1MB数据,机械硬盘是20ms,SSD只须要1ms。更改硬盘达到速度的提高可能让福报程序员能够掉更少的头发,得到更多的休息。数据库

相关文章
相关标签/搜索