一提到mysql,总有人说磁盘IO,到底什么是磁盘IO?

article/2025/11/5 21:15:40

为什么mysql的innodb存储引擎选择了B+树,这个和磁盘的特性有着非常大的关系。

我们先来看下磁盘上的物理结构。

 

如果我们简化一下,可以这么看

再看几张模型图

 

 

一个磁盘由大小相同且同轴的圆形盘片组成,磁盘可以转动,各个磁盘必须同步转动,不然你转你的,我转我的,不就乱套了吗?

在磁盘的一侧有磁头支架,磁头支架固定了一组磁头,每个磁头负责存取一个磁盘的内容。磁头不能转动,能读取到磁盘的内容,是依靠于磁盘的转动。

这样说可能不太好理解,可以试着想象一下唱片机放歌时的场景,感觉差不多的道理。

盘片被划分成一系列同心环,主轴就是盘片中心,每个同心环都是一个磁道。每个磁道的外围都形成一个柱面。

磁道被沿半径线划分成一个个小的段,每个段叫做一个扇区,每个扇区是磁盘的最小存储单元也是最小读写单元。现在磁盘扇区一般是512个字节~4k个字节。

磁盘上每个数据都必须用一个三维地址来标示,就是上面提到的:柱面号、盘面号、扇区号。

类似于我们使用的地图软件上的三维坐标,磁盘也有自己的坐标,这三个元素确定了,位置就确定了。

读/写磁盘上某一指定数据需要下面步骤:

(1)  首先根据柱面号,移动磁头支架,使磁头移动到相应的柱面上,这一过程被称为定位或查找。

(2)所有磁头都定位到柱面号对应的磁道上后,这时根据盘面号来确定指定盘面号上的具体磁道。

(3) 盘面确定以后,盘片开始旋转,将指定扇区号的磁道段移动至磁头下。

经过上面步骤,指定数据的存储位置就被找到了。这时就可以开始读/写操作了。

可以看见,磁盘读取依靠的是机械运动,分为寻道时间、旋转延迟、传输时间三个部分,这三个部分耗时相加就是一次磁盘IO的时间,一般大概9ms左右。

寻道时间(seek)是将读写磁头移动至正确的磁道上所需要的时间,这部分时间代价最高;

旋转延迟时间(rotation)是磁盘旋转将目标扇区移动到读写磁头下方所需的时间,取决于磁盘转速;

数据传输时间(transfer)是完成传输数据所需要的时间,取决于接口的数据传输率,在纳秒级,远小于前两部分消耗时间。

磁盘读取时间成本是访问内存的几百倍到几万倍之间。

既然这么慢,为了提高效率,要尽量减少磁盘I/O。为了达到这个目的,磁盘往往不是严格按需读取,而是每次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存,这个称之为预读。

这样做的理论依据是计算机科学中著名的局部性原理:

当一个数据被用到时,其附近的数据也通常会马上被使用。

程序运行期间所需要的数据通常比较集中。

由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),一般来说,磁盘的顺序读的效率是随机读的40到400倍都有可能,顺序写是随机写的10到100倍 。因此对于具有局部性的程序来说,预读可以提高I/O效率。因为程序接下来可能用到的数据已经提前预读进来了。

预读的长度一般为页(page)的整倍数。

页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和磁盘存储区分割为连续的大小相等的块,每个存储块称为一页,页大小通常为4k当然也有16K的,主存和磁盘以页为单位交换数据。

当程序要读取的数据不在主存中时,会触发一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,然后程序继续运行。

按照磁盘的这种性质,如果是一个页存放一个B+树的节点,自然是可以存放很多数据的,比如InnoDB里,默认定义的B+树的节点大小是16KB,这就是说,假如一个Key是8个字节,那么一个节点可以存放大约1000个Key。

同时InnoDB每一次磁盘I/O,读取的都是 16KB的整数倍的数据。也就是说InnoDB在节点的读写上是可以充分利用磁盘顺序IO的高速读写特性。

同时按照B+树数据结构来说,在叶子节点这一层,所有记录的主键按照从小到大的顺序排列,并且形成了一个双向链表。

同一层的非叶子节点也互相串联,形成了一个双向链表。

那么在实际读写的时候,很大的概率相邻的节点会放在相邻的页上,又可以充分利用磁盘顺序IO的高速读写特性。

所以我们对MySQL优化的一大方向就是尽可能的多让数据顺序读写,少让数据随机读写。


http://chatgpt.dhexx.cn/article/IMNEokcu.shtml

相关文章

一寸照像素和厘米的关系及换算

一寸照的概念: 照片的一寸和二寸是指照片的边长度,而不是对角线。 这里的寸指的是英寸 厘米和英寸: 1 厘米=0.3937 英寸 1 英寸=2.54 厘米 一寸照的厘米概念: 一寸照规格是宽*高2.5cm*3.5cm ,换…

CSS像素单位

一、px 整个屏幕的一个像素点。 二、em单位 1em:16px浏览器的默认值1em 基准值(16px)* number(1) 16px2em 基准值(16px)* number(2) 32px 当默认值改了&#xff0c…

python 找出矩阵中非零数

转载于:https://www.cnblogs.com/fuhang/p/9185840.html

可逆矩阵的概念 逆矩阵的求解方法总结

可逆矩阵的概念:设A是一个n阶矩阵,如果存在n阶矩阵B,使得ABBAE,则称矩阵A为可逆矩阵,且B称为A的逆矩阵。 逆矩阵的求解方法总结: 1.待定系数法 利用定义进行求解,设A是一个n阶矩阵,如…

直观理解:为什么A为 n 阶满秩方阵时,Ax=0 只有零解?

本篇博客仅记录一下我个人思考的一点想法,方便以后回顾。并不严谨,希望给大家提供一点直观的理解。 通过上边的变形,我们可以看出 A x Ax Ax的本意就是用 x [ x 1 x 2 . . . x n ] x[x_{1} x_{2} ... x_{n}] x[x1​x2​...xn​]作为系数对 A…

【矩阵论笔记】矩阵特征矩阵的行列式因子、不变因子、初等因子

矩阵的特征值矩阵是由矩阵特征值 λ \lambda λ构成的矩阵。包含三个运算: 1、互换两行(列) 2、某行(列)乘非零常数 3、某行(列)乘多项式后加到另一行 n阶 λ \lambda λ矩阵可逆的充要条件是&a…

matlab求矩阵的非,matlab矩阵非零个数 Matlab如何提取非零元素

matlab 如何把一个矩阵中的非零数取出组成一行 >> A=randi([0 4],4) A = 4 2 1 0 2 3 2 3 0 4 0 2 0 3 0 0 >> B=nonzeros(A) B = 4 2 2 3 4 3 1 2 3 2 matlab中怎么求数组中非零元素的个数 matlab中求矩阵中非零元素的均值怎么求啊? 代码: a(a==0)=NaN; mean(a,…

【随心所记】矩阵A的行列式不等于0,是A可逆的充要条件吗?答:是这样的

题目 解析 注意,谈到 可逆矩阵 A,那么A一定是 方阵 哈!!!即 n行n列。

Matlab与线性代数 -- 寻找矩阵的非零元素

本微信图文详细介绍了Matlab中find函数的用法。

numpy 求矩阵非零元素的均值

假如我们有一个矩阵A,想要求其中的非零元素的均值,计算方式是: 直接用mean来求的话,分母是所有元素的个数,不符合我们的要求。 在matlab中,这样做: mean(AA(AA~0))numpy: import …

零矩阵题解

题目 编写一种算法,若M N矩阵中某个元素为0,则将其所在的行与列清零。 示例 1: 输入: [[1,1,1],[1,0,1],[1,1,1] ] 输出: [[1,0,1],[0,0,0],[1,0,1] ]示例 2: 输入: [[0,1,2,0],[3,4,5,2],[…

零矩阵00

题目链接 零矩阵 题目描述 注意 无 解答思路 用另外两个数组分别保存对应的行和列是否出现了0,后续在填充元素时则根据这两个数组中对应的值确定是否填0 代码 class Solution {public void setZeroes(int[][] matrix) {int m matrix.length;int n matrix[0…

矩阵零空间

矩阵A的零空间就Ax0的解的集合。 零空间的求法:对矩阵A进行消元求得主变量和自由变量;给自由变量赋值得到特解;对特解进行线性组合得到零空间。 假设矩阵如下: 对矩阵A进行高斯消元得到上三角矩阵U,继续化简得到最简…

从0了解矩阵——矩阵的本质

矩阵是大学线性代数课程里的内容,当时学的时候虽然一头雾水,不过,牵扯到的问题基本上都是一些加减乘除,所以,我的线性代数课程倒是拿了不错的成绩。虽然分数考得不错,但是,直到毕业后很多年&…

matlab中换行操作

在写matlab程序时,如果一行代码太长,不利于可读性和美观,那么我们可以使用三个点号(...)来实现换行。 示例如下: 我想打印一个字符a,正常写fprintf(%s\n,a ),是没有问题的 fprint…

matlab中.mat文件用法

保存数据 在工作区右击“新建”,输入变量名双击变量,将excel数据复制到窗口关闭窗口,右击另存为,以“.mat”为后缀进行保存 导入数据 双击文件区域mat文件即可完成导入 注: 导入的变量与保存时的变量一致&#…

Matlab中table类型使用技巧

在处理一些较复杂的表格数据时,直接导入为数组并不方便处理,这时候需要使用table类型数据来更好的存储和处理数据。 例如,在处理某实验数据时,将excel直接导入至matlab中的table数据类型,读取代码为: data …

MATLAB中的for循环

MATLAB中的for循环 格式 for i开始:步长(步长为1可省略):结束 。。。。 end 示例1 输出1至10 代码 输出 示例2 输出10以内的奇数 代码 输出

MATLAB中的rands函数

rands 函数一般是用在神经网络的权值和阈值的初始化时,范围是-1到1。 格式:rands(m,n) 随机生成一个m行n列的矩阵,且其中的各元素范围在-1到1之间。 举例:

Matlab中@的用法

申明: 本博客初衷是作为博主的笔记,转载自CSDN博主:雾里_看花。 原文摘自: 1.https://blog.csdn.net/weixin_38009585/article/details/81016997; 用法一: :函数句柄(function handle),它既是…