【MySQL】索引——索引的引入、认识磁盘、磁盘的组成、扇区、磁盘访问、磁盘和MySQL交互、索引的概念

news2024/10/2 10:31:36

文章目录

  • MySQL
    • 1. 索引的引入
    • 2. 认识磁盘
      • 2.1 磁盘的组成
      • 2.2 扇区
      • 2.3 磁盘访问
    • 3. 磁盘和MySQL交互
    • 4. 索引的概念
      • 4.1 索引测试
      • 4.2 Page
      • 4.3 单页和多页情况

MySQL

在这里插入图片描述

  

1. 索引的引入

  海量表在进行普通查询的时候,效率会非常的慢,但是索引可以解决这个问题。

--构建一个8000000条记录的数据
--构建的海量表数据需要有差异性,所以使用存储过程来创建
-- 产生随机字符串
delimiter $$
create function rand_string(n INT)
returns varchar(255)
begin
declare chars_str varchar(100) default
'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';
declare return_str varchar(255) default '';
declare i int default 0;
while i < n do
set return_str =concat(return_str,substring(chars_str,floor(1+rand()*52),1));
set i = i + 1;
end while;
return return_str;
end $$
delimiter ;
--产生随机数字
delimiter $$
create function rand_num()
returns int(5)
begin
declare i int default 0;
set i = floor(10+rand()*500);
return i;
end $$
delimiter ;
--创建存储过程,向雇员表添加海量数据
delimiter $$
create procedure insert_emp(in start int(10),in max_num int(10))
begin
declare i int default 0;
set autocommit = 0;
repeat
set i = i + 1;
insert into EMP values ((start+i)
,rand_string(6),'SALESMAN',0001,curdate(),2000,400,rand_num());
until i = max_num
end repeat;
commit;
end $$
delimiter ;
-- 执行存储过程,添加8000000条记录
call insert_emp(100001, 8000000);

  

查询员工编号为998877的员工

select * from EMP where empno=998877;

  本机一个人来操作就要耗时接近5秒,所有如果放在公网中,假如同时有1000个人并发查询,那很可能就死机。

  
解决方法,创建索引

alter table EMP add index(empno);

  

换一个员工编号,测试看看查询时间

select * from EMP where empno=123456;

  

2. 认识磁盘

  磁盘(disk)是指利用磁记录技术存储数据的存储器。

  磁盘是计算机主要的存储介质,可以存储大量的二进制数据,并且断电后也能保持数据不丢失。早期计算机使用的磁盘是软磁盘(Floppy Disk,简称软盘),如今常用的磁盘是硬磁盘(Hard disk,简称硬盘)。

  

在这里插入图片描述

  

2.1 磁盘的组成

盘片:

  盘片:是存储数据的主要介质,通常由铝、玻璃或陶瓷等材料制成,表面涂有磁性物质,数据就记录在这些磁性涂层上。

  例如,一个磁盘可能有多个盘片,像多层蛋糕一样叠放。
在这里插入图片描述

  

磁道:

  磁道是磁盘表面上的一组同心圆。数据在磁盘上的存储就是分布在这些磁道上的。可以把磁道想象成一个环形的跑道,数据就如同运动员在跑道上的位置。每个磁道被划分成多个扇区,扇区是数据读写的基本单位。磁道的密度会影响磁盘的存储容量和数据传输速度。

  例如,磁盘外圈的磁道周长较长,能存储更多数据,而内圈磁道周长较短,存储的数据相对较少。在磁盘工作时,磁头会沿着磁道移动来读取或写入数据。

  
在这里插入图片描述

  

2.2 扇区

扇区:

  扇区是磁盘存储的基本单位它的大小一般是固定的,常见为 512 字节。比如要存数据到磁盘,就会按扇区来存放。扇区有编号,从 0 开始。

  相邻扇区组成磁道,多个磁道构成盘面。就算数据不满一个扇区,也会占一整个扇区的空间。扇区能让磁盘存储更高效、管理数据更方便。

  数据库文件,本质其实就是保存在磁盘的盘片当中。也就是上面的一个个小格子中,就是我们经常所说的扇区。当然,数据库文件很大,也很多,一定需要占据多个扇区。

  

定位扇区:

  通常存储着磁盘的重要信息,比如分区表,这能告诉系统磁盘如何划分区域来存储不同的数据。还可能存有引导记录,帮助计算机启动时找到操作系统的位置并加载。定位扇区就像是磁盘的“地图指南”和“启动钥匙”。

  例如,当计算机开机时,会首先读取定位扇区的信息,来知道如何找到并启动系统

在这里插入图片描述
  

  定位扇区:通常是指在磁盘操作中,为了特定目的而专门标识或指定的扇区。它可能具有特殊的用途或被系统用于特定的功能,例如存储磁盘的关键信息,如分区表、引导记录等。

  普通扇区:则是磁盘上用于一般数据存储和读写的扇区。

  

  我们现在已经能够在硬件层面定位,任何一个基本数据块了(扇区)。那么在系统软件上,就直接按照扇区(512字节,部分4096字节),进行IO交互吗?不是

  如果操作系统直接使用硬件提供的数据大小进行交互,那么系统的IO代码,就和硬件强相关,换言之,如果硬件发生变化,系统必须跟着变化

  从目前来看,单次IO512字节,还是太小了。IO单位小,意味着读取同样的数据内容,需要进行多次磁盘访问,会带来效率的降低。

  之前文件系统,就是在磁盘的基本结构下建立的,文件系统读取基本单位,就不是扇区,而是数据块。所以,系统读取磁盘,是以块为单位的,基本单位是 4KB 。

  

2.3 磁盘访问

  磁盘随机访问(Random Access)与连续访问(Sequential Access)

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

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

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

  磁盘是通过机械运动进行寻址的,随机访问不需要过多的定位,故效率比较高。

  

3. 磁盘和MySQL交互

  而 MySQL 作为一款应用软件,可以想象成一种特殊的文件系统。它有着更高的IO场景,所以,为了提高基本的IO效率, MySQL 进行IO的基本单位是 16KB。

  也就是说,磁盘这个硬件设备的基本单位是 512 字节,而 MySQL InnoDB引擎 使用 16KB 进行IO交互。MySQL 和磁盘进行数据交互的基本单位是 16KB 。 这个基本数据单元,在 MySQL 这里叫做page。

mysql> SHOW GLOBAL STATUS LIKE 'innodb_page_size';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| Innodb_page_size | 16384 | -- 16*1024=16384
+------------------+-------+
1 row in set (0.01 sec)

  

总结:

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

  MySQL 的 CURD 操作,都需要通过计算,找到对应的插入位置,或者找到对应要修改或者查询的数据。

  而只要涉及计算,就需要CPU参与,而为了便于CPU参与,一定要能够先将数据移动到内存当中。

  所以在特定时间内,数据一定是磁盘中有,内存中也有。后续操作完内存数据之后,以特定的刷新策略,刷新到磁盘。而这时,就涉及到磁盘和内存的数据交互,也就是IO了。而此时IO的基本单位就是Page。

  为了更好的进行上面的操作, MySQL 服务器在内存中运行的时候,在服务器内部,就申请了被称为 Buffer Pool 的的大内存空间,来进行各种缓存。其实就是很大的内存空间,来和磁盘数据进行IO交互。

  为何更高的效率,一定要尽可能的减少系统和磁盘IO的次数。

  

4. 索引的概念

  MySQL 索引是一种用于提高数据库查询和操作性能的数据结构。

  它就像是一本书的目录,通过索引,MySQL 能够更快地定位和获取所需的数据,而不必遍历整个数据表。

  所以索引能够显著提高数据库的查询速度,可能让速度提升数百甚至数千倍,只需执行正确的 create index 操作,无需对内存、程序或 SQL 语句进行大的改动。

  同时也强调了索引并非毫无代价。虽然能加快查询,但会降低插入、更新和删除操作的速度,因为这些写操作会产生大量的 I/O 开销。这意味着在使用索引时需要权衡查询性能和写操作性能之间的平衡。

  

  关于常见索引的分类:

  主键索引(primary key):用于唯一标识表中的每一行记录,确保其值的唯一性和非空性。例如,在学生表中,学号可以作为主键索引。

  唯一索引(unique):确保某一列的值不重复,但允许为 NULL。比如,在用户表中,身份证号可以设置为唯一索引。

  普通索引(index):用于加快数据的查询速度,但不保证列值的唯一性。比如,在商品表中,商品名称可以创建普通索引。

  全文索引(fulltext):主要用于解决中文文本的索引问题,能够高效地在大量文本数据中进行搜索。例如,在文章表中,文章内容可以创建全文索引来快速搜索特定的关键词或短语。

  

4.1 索引测试

建立测试表:

mysql> create table if not exists user (
    -> id int primary key,
    -> age int not null,
    -> name varchar(16) not null
    -> );
Query OK, 0 rows affected (0.01 sec)

在这里插入图片描述

  

插入多条记录:

mysql> insert into user (id, age, name) values(3, 18, '杨过');
Query OK, 1 row affected (0.01 sec)

mysql> insert into user (id, age, name) values(4, 16, '小龙女');
Query OK, 1 row affected (0.00 sec)

mysql> insert into user (id, age, name) values(2, 26, '黄蓉');
Query OK, 1 row affected (0.01 sec)

mysql> insert into user (id, age, name) values(5, 36, '郭靖');
Query OK, 1 row affected (0.01 sec)

mysql> insert into user (id, age, name) values(1, 56, '欧阳锋');
Query OK, 1 row affected (0.00 sec)

在这里插入图片描述

  

查看插入结果:

mysql> select * from user;

在这里插入图片描述
  

  我们会发现排序竟然默认是有序的。

  

4.2 Page

单个Page:

  MySQL 中要管理很多数据表文件,而要管理好这些文件,就需要 先描述,在组织 ,我们目前可以简单理解成一个个独立文件是有一个或者多个Page构成的。

  不同的 Page ,在 MySQL 中,都是 16KB ,使用 prev 和 next 构成双向链表。

  因为有主键的问题, MySQL 会默认按照主键给我们的数据进行排序,从上面的Page内数据记录可以看出,数据是有序且彼此关联的。

  
在这里插入图片描述

  

多个Page:

  在上面页模式中,只有一个功能,就是在查询某条数据的时候直接将一整页的数据加载到内存中,以减少硬盘IO次数,从而提高性能。但是,我们也可以看到,现在的页模式内部,实际上是采用了链表的结构,前一条数据指向后一条数据,本质上还是通过数据的逐条比较来取出特定的数据。

  如果有1千万条数据,一定需要多个Page来保存1千万条数据,多个Page彼此使用双链表链接起来,而且每个Page内部的数据也是基于链表的。那么,查找特定一条记录,也一定是线性查找。这效率也太低了。

在这里插入图片描述

  

4.3 单页和多页情况

单页情况:

  针对上面的单页Page,我们能否也引入目录呢?当然可以。

  那么当前,在一个Page内部,我们引入了目录。比如,我们要查找id=4记录,之前必须线性遍历4次,才能拿到结果。现在直接通过目录2[3],直接进行定位新的起始位置,提高了效率。现在我们可以再次正式回答上面的问题了,为何通过键值 MySQL 会自动排序?可以很方便引入目录。

在这里插入图片描述

  

多页情况:

  MySQL 中每一页的大小只有 16KB ,单个Page大小固定,所以随着数据量不断增大, 16KB 不可能存下所有的数据,那么必定会有多个页来存储数据。

  在单表数据不断被插入的情况下, MySQL 会在容量不足的时候,自动开辟新的Page来保存新的数据,然后通过指针的方式,将所有的Page组织起来。

  其实目录页的本质也是页,普通页中存的数据是用户数据,而目录页中存的数据是普通页的地址。

在这里插入图片描述

… …

          

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

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

相关文章

COMSOL金属氢化物-放氢过程

在此记录下放氢过程的软件设置思路 1、采用的是"达西定律""层流" 物理场&#xff0c;其中"层流"物理场选择了”弱可压缩流动“&#xff0c;这里主要是选择”可压缩流动“的话&#xff0c;算出来的瞬时流量值跟实测差距太大了。 2、设置"达西…

【Elegant Programming (优雅的编程)】如何用合理的封装优雅的化解三层以上的 if-else ?

&#x1f449;博主介绍&#xff1a; 博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家&#xff0c;WEB架构师&#xff0c;阿里云专家博主&#xff0c;华为云云享专家&#xff0c;51CTO 专家博主 ⛪️ 个人社区&#x…

数据结构与算法 - 二叉树

1. 概述 二叉树是这么一种树状结构&#xff1a;每个节点最多有两个孩子&#xff0c;左孩子和右孩子 完全二叉树&#xff1a;是一种二叉树结构&#xff0c;除了最后一层以外&#xff0c;每一层都必须填满&#xff0c;填充时要遵循从左到右 平衡二叉树&#xff1a;是一种二叉树…

基础算法之模拟

1P1093 [NOIP2007 普及组] 奖学金 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1093https://www.luogu.com.cn/problem/P1093 #include<iostream> #include<algorithm> using namespace std; struct stu {int num;//编号int c…

尚品汇-首页三级分类实现-nginx静态代理生成的静态页面(二十六)

目录&#xff1a; &#xff08;1&#xff09;问题详解 &#xff08;2&#xff09;首页商品分类实现 &#xff08;3&#xff09;修改web-all模块 &#xff08;4&#xff09;页面渲染 &#xff08;1&#xff09;问题详解 &#xff08;2&#xff09;首页商品分类实现 前面做了…

【书生大模型实战营(暑假场)】入门任务三 Python 关卡

入门任务二 Python 关卡 参考&#xff1a; 教程任务 1 闯关任务 1.1 使用 Python 实现 wordcount import stringdef wordcount(text):# 去除标点符号text text.translate(str.maketrans(, , string.punctuation))# 转换为小写text text.lower()# 分割字符串成单词列表wo…

CH571F蓝牙orUSB摇杆鼠标

演示视频&#xff1a; 短视频刷个爽 程序基本上是基于官方的例程上改的&#xff0c;用到的例程有&#xff1a;蓝牙的HID_Mouse,USB的CompoundDev&#xff0c;还有ADC&#xff0c;按键中断。 主要原理 就是ADC采集采集摇杆电压&#xff0c;通过蓝牙HID或者USB的HID发送给电脑或…

文心一言 VS 讯飞星火 VS chatgpt (317)-- 算法导论22.3 9题

九、请给出如下猜想的一个反例&#xff1a;如果有向图G包含一条从结点u到结点v的路径&#xff0c;则任何对图G的深度优先搜索都将导致v.d⩽u.f。如果要写代码&#xff0c;请用go语言。 文心一言&#xff1a; 首先&#xff0c;我们需要澄清问题中的几个关键点。在图的深度优先…

想做抖音短视频,视频素材去哪里找啊?

各位抖音上的短视频创作者们&#xff0c;是否曾幻想过自己的作品能够在全网爆火&#xff0c;却常因为缺少那些能够让视频更加生动的素材而感到困扰&#xff1f;不用担心&#xff0c;今天我要为大家介绍几个优秀的视频素材网站&#xff0c;让你的抖音之路顺风顺水&#xff01; …

Linux系统中的高级用户空间与内核空间交互技术

Linux作为一种开源操作系统&#xff0c;具有良好的稳定性、安全性和自定制性&#xff0c;因而在各种设备和场景中得到广泛应用。作为Linux系统的核心组成部分&#xff0c;内核空间与用户空间交互技术对系统性能和功能扩展起着关键作用。本文将深入探讨Linux系统中的高级用户空间…

Vue Vine:带给你全新的 Vue 书写体验!

你好&#xff0c;我是 Kagol&#xff0c;个人公众号&#xff1a;前端开源星球。 上个月和 TinyVue 的小伙伴们一起参加了 VueConf 24 大会&#xff0c;有幸认识沈青川大佬&#xff0c;并了解了他的 Vue Vine 项目&#xff0c;Vue Vine 让你可以在一个文件中通过函数方式定义多…

系统化学习 H264视频编码(05)码流数据及相关概念解读

说明&#xff1a;我们参考黄金圈学习法&#xff08;什么是黄金圈法则?->模型 黄金圈法则&#xff0c;本文使用&#xff1a;why-what&#xff09;来学习音H264视频编码。本系列文章侧重于理解视频编码的知识体系和实践方法&#xff0c;理论方面会更多地讲清楚 音视频中概念的…

Nginx进阶-常见配置(二)

一、nginx 日志配置 nginx 日志介绍 nginx 有一个非常灵活的日志记录模式,每个级别的配置可以有各自独立的访问日志, 所需日志模块 ngx_http_log_module 的支持&#xff0c;日志格式通过 log_format 命令来定义&#xff0c;日志对于统计和排错是非常有利的&#xff0c;下面总…

【TwinCAT3教程】TwinCAT3 PLC 简单程序编写与调试

一、PLC 简单程序编写 1.1 新建TwinCAT3项目 (1)打开 TwinCAT 3,点击 New TwinCAT Project 新建 TC3 项目。 (2)选择 TwinCAT Project,输入项目名称和项目保存路径,然后点击确定。 1.2 添加PLC项目 1.2.1 步骤 (1)在树形资源管理器右键点击 PLC,选择 添加新项 新…

STM32F28335实验:继电器

继电器控制电机&#xff1a; 5s启动 5s停止 循环 管脚图&#xff1a; 管脚用的是GPIO15 驱动&#xff1a; beep.c /** leds.c** Created on: 2024年8月2日* Author: Administrator*/#include<relay.h>/***************************************************…

【算法设计题】查找给定结点的双亲结点(二叉树),第3题(C/C++)

目录 第3题 查找给定结点的双亲结点&#xff08;二叉树&#xff09; 得分点&#xff08;必背&#xff09; 题解 定义函数和初始化变量&#xff1a; 处理特殊情况&#xff1a; 遍历树&#xff1a; 中序遍历左子树&#xff1a; 处理右子树&#xff1a; 返回结果&#x…

LSTM实战之预测股票

&#x1f4c8; 用PyTorch搭建LSTM模型&#xff0c;轻松预测股票价格&#xff01;&#x1f680; Hey小伙伴们&#xff0c;今天给大家带来一个超级实用的项目教程——如何用PyTorch和LSTM模型来预测股票价格&#xff01;&#x1f31f; &#x1f50d; 项目背景 我们都知道股市是…

《Unity3D网络游戏实战》学习与实践--制作一款大乱斗游戏

角色类 基类Base Human是基础的角色类&#xff0c;它处理“操控角色”和“同步角色”的一些共有功能&#xff1b;CtrlHuman类代表“操控角色”​&#xff0c;它在BaseHuman类的基础上处理鼠标操控功能&#xff1b;SyncHuman类是“同步角色”类&#xff0c;它也继承自BaseHuman&…

MySQL的数据结构B+tree以及SQL优化

首先呢&#xff0c;我们知道MySQL的数据结构为Btree,那么其结构究竟是什么样的&#xff0c;为什么选择Btree&#xff0c;而不选择Btree。下面我们从其结构分析 1.Btree平衡多路查找树 B-tree结构的数据可以让系统高效的找到数据所在的磁盘块。为了描述B-Tree,首先定义一条记录…

入门mem0.NET

入门mem0.NET 安装包 如果你的项目使用了EntityFrameworkCore,那么你可以跟随这个教程走 <ItemGroup><PackageReference Include"mem0.NET" Version"0.1.7" /><PackageReference Include"mem0.NET.Qdrant" Version"0.1.7…