MySQL索引特性(上)

目录

索引的重要

 案例

认识磁盘 

MySQL与存储

先来研究一下磁盘

 扇区

定位扇区

结论 

 磁盘随机访问与连续访问

MySQL与磁盘交互基本单位

建立共识

 索引的理解

建立测试表

 插入多条记录

局部性原理 


所有的MySQL的操作(增删查改)全部都是在MySQL当中的内存中进行的,MySQL在启动的时候会预先帮我们开辟一大块空间,开辟后在合适的时候把数据的操作体现在内存级,然后MySQL再把数据定期刷新到我们对应的外设也就是磁盘当中做持久化;索引也是如此 

索引的重要

索引:提高数据库的性能,索引是物美价廉的东西了。不用加内存,不用改程序,不用调sql,只要执行正确的 create index ,查询速度就可能提高成百上千倍。但是天下没有免费的午餐,查询速度的提高是以插入、更新、删除的速度为代价的,这些写操作,增加了大量的IO。所以它的价值,在于提高一个海量数据的检索速度(查是快了);    

常见索引分为:

1. 主键索引(primary key)

2. 唯一索引(unique)

3. 普通索引(index)

4. 全文索引(fulltext)--解决中子文索引问题。

 案例

先整一个海量表,在查询的时候,看看没有索引时有什么问题?

 向MySQL中导入mysql> source /home/wwz/index_data.sql

 导入后会在数据库中创建big_index库;use bit_insex;(因为数据量有点大所以根据机器导入时间不同)

mysql> show tables;//因为数据量好多所以不要selece *全部字段列否则要等待好久

mysql> select * from EMP limit 5;//可以列出部分少的

 查询员工编号为998877的员工

mysql> select * from EMP where empno=998877;

查询一条信息就用到5秒多,甚至有的机器因为数据量太大(亿级)直接killed服务(占资源太多了,os直接kill你了)

可以看到耗时5.75秒,这还是在本机一个人来操作,在实际项目中,如果放在公网中,假如同时有1000个人并发查询,那很可能就死机。

解决办法创建索引mysql> alter table EMP add index(empno);//加索引也需要时间

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

mysql> select * from EMP where empno=1234567;//发现现在非常快(零点几秒)

认识磁盘 

MySQL与存储

MySQL 给用户提供存储服务,而存储的都是数据,数据在磁盘这个外设当中。磁盘是计算机中的一个机 械设备,相比于计算机其他电子元件,磁盘效率是比较低的,在加上IO本身的特征,可以知道,如何提 交效率,是 MySQL 的一个重要话题。

先来研究一下磁盘

 扇区

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

从上图可以看出来,在半径方向上,距离圆心越近,扇区越小,距离圆心越远,扇区越大那么,所有扇区都是默认512字节吗?目前是的,我们也这样认为。因为保证一个扇区多大,是由比特位密度决定的。 不过最新的磁盘技术,已经慢慢的让扇区大小不同了,不过我们现在暂时不考虑。

我们在使用Linux,所看到的大部分目录或者文件,其实就是保存在硬盘当中的。(当然,有一些内存文 件系统,如: proc , sys 之类,我们不考虑)

数据库文件,本质其实就是保存在磁盘的盘片当中,就是一个一个的文件

 ll /var/lib/mysql    #我们目前MySQL中的文件


自己定义的数据库,里面有数据表

 所以最基本的,找到一个文件的全部,本质就是在磁盘找到所有保存文件的扇区。 而我们能够定位任何一个扇区,那么便能找到所有扇区,因为查找方式是一样的。

定位扇区

1. 柱面(磁道): 多盘磁盘,每盘都是双面,大小完全相等。那么同半径的磁道,整体上便构成了一个柱面

2. 每个盘面都有一个磁头,那么磁头和盘面的对应关系便是1对1的

3. 所以,我们只需要知道,磁头(Heads)、柱面(Cylinder)(等价于磁道)、扇区(Sector)对应的编号。即可在磁盘上定位所要访问的扇区。这种磁盘数据定位方式叫做CHS 。不过实际系统软件使用的并不是CHS (但是硬件是),而是LBA ,一种线性地址,可以想象成虚拟地址与物理地址。系统将 LBA 地址最后会转化成为 CHS ,交给磁盘去进行数据读取。不过,我们现在不关心转化细节,知道这个东西,让我们逻辑自洽起来即可。

结论 

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

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

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

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

 磁盘随机访问与连续访问

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

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

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

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

MySQL与磁盘交互基本单位

首先MySQL是一款应用软件,他在系统角度就是应用进程,在网络层是应用服务所以都是在应用层的,可以想象成一种特殊的文件系统。它有着更高的IO场景,所以,为了提高基本的IO效率, MySQL进行IO的基本单位是16KB (后面统一使用 InnoDB 存储引擎讲解)

 mysql> show global status like 'innodb_page_size';
16384=1024*16;可以看到16KB大小(1KB=1024B)

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

建立共识

MySQL 中的数据文件,是以page(16KB)为单位保存在磁盘当中的。(在物理上MySQL存数据时以page为单位塞到文件里)

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

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

 所以在特定时间内,数据一定是磁盘中有,内存中也有(相当于我把数据加载到内存里,当我改完了再刷新,也是以page为单位刷新覆盖历史的page数据)。后续操作完内存数据之后,以特定的刷新策略,刷新到磁盘。而这时,就涉及到磁盘和内存的数据交互,也就是IO了(其实也就是把MySQL的数据拷贝给os,单位是16KB,接下来让os强制的把16KB的数据或者整个缓冲区的数据持久化刷到磁盘里)。而此时IO的基本单位就是Page。

 为了更好的进行上面的操作, MySQL 服务器在内存中运行的时候,在服务器内部,就申请了被称为Buffer Pool 的的大内存空间,来进行各种缓存。其实就是很大的内存空间,来和磁盘数据进行IO交互。(MySQL是用c/c++写的,他开辟空间就是new或者malloc)

vim /etc/my.cnf          //可以看到默认128M大小

 为了更高的效率,一定要尽可能的减少系统和磁盘IO的次数;(就类比于我写100MB的数据,我一次把100MB的数据写到磁盘上和分100次每次1MB写到磁盘上来看,一次性的效率更高,因为只需要一次寻址找到磁盘当中的位置即可,如果100次的话可能进行100次寻址意味着磁盘盘片要转,磁头要摆)

 索引的理解

建立测试表

mysql> create table if not exists user(
    -> id int primary key,
    -> age int not null,
    -> name varchar(16) not null
    -> );

一定要添加主键,只有这样才会默认生成主键索引


默认就是InnoDB存储引擎

 插入多条记录

插入五条记录(随机插入的顺序)

查找发现我明明是无顺序插入的,最后是顺序插入


我们向一个具有主键的表中乱序插入数据,发现数据会自动排序;

 在MySQL内部(自己启动变成一个服务进程)一定需要并且会存在大量的page,也就决定了母三千里必须要将多个同时存在的page管理起来!需要先描述再组织;所以不要简单认为page是一个内存块(16KB大小),page内部也必须写入对用的管理信息!
struct page(

 struct page*prev,
 struct page * next,
 char buffer[num];
);----16KB                     
所以在MySQL里申请一个page就是new page;然后将所有的page用'链表'的形式管理起来(此链表非彼链表);-----在buffer pool内部,对MySQL中的page进行了一个建模!

为何MySQL和磁盘进行IO交互的时候,要采用Page的方案进行交互呢?用多少,加载多少不香吗? 其实多加载的就是预加载,可以有效减少IO次数;

如上面的5条记录,如果MySQL要查找id=2的记录,第一次加载id=1,第二次加载id=2,一次一条记录,那 么就需要2次IO。如果要找id=5,那么就需要5次IO。
但如果这5条(或者更多)都被保存在一个Page中(16KB,能保存很多记录),那么第一次IO查找id=2的时候,整个Page会被加载到MySQL的Buffer Pool中,这里完成了一次IO。但是往后如果在查找id=1,3,4,5 等,完全不需要进行IO了,而是直接在内存中进行了。所以,就在单Page里面,大大减少了IO的次数。

你怎么保证,用户一定下次找的数据,就在这个Page里面?我们不能严格保证,但是有很大概率,因为有局部性原理。 往往IO效率低下的最主要矛盾不是IO单次数据量的大小,而是IO的次数。

局部性原理 

计算机的局部性原理是指在程序执行过程中,访问的数据和指令往往集中在某些局部区域,而不是分散在整个存储空间中。这个原理有两个主要方面:
1. 时间局部性(Temporal Locality)如果程序中的某个数据项一旦被访问,那么在不久的将来它很可能被再次访问这意味着最近被使用过的内存位置很可能会被再次使用,因此计算机会将这些位置的数据保留在高速缓存中,以便更快地访问

2. 空间局部性(Spatial Locality)一旦某个数据被访问,与该数据附近的数据很可能也会被访问。例如,如果程序访问了一个数组元素,那么其相邻的元素也很可能在不久之后被访问。为了利用空间局部性,计算机系统通常会将邻近的数据项也加载到缓存中,以便减少访问延迟。
局部性原理是计算机系统中优化性能的重要依据,因为它允许系统在内存和处理器之间的数据传输更有效率,减少了存储器访问的时间和能量消耗。通过合理利用局部性,计算机可以更快速地执行程序,提高整体性能和响应速度。

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

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

相关文章

网友提问:HTML CSS JS很低级吗?

这话听起来就像有人在说披萨只是面团加奶酪,完全忽略了上面的美味配料和烘烤的艺术啊!HTML、CSS、JS这三位可是前端开发的铁三角,它们一点都不“低级”,反而相当关键。 HTML就像是房子的骨架,没有它,网页就…

【iOS】——MRC

一、引用计数 内存管理的核心是引用计数器,用一个整数来表示对象被引用的次数,系统需要根据引用计数器来判断对象是否需要被回收。 在每次 RunLoop 迭代结束后,都会检查对象的引用计数器,如果引用计数器等于 0,则说明…

单链表算法 - 链表分割

链表分割_牛客题霸_牛客网现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的。题目来自【牛客题霸】https://www.nowcoder.com/practice/0e27e0b064de4eacac178676ef9c9d70思路: 代码: /* struct ListNode {int val;struct List…

烧掉一个亿就为造好一把椅子,西昊如何策划人体工学椅极致产品力

2011年到2015年这4年期间,功能单一,价值雷同的椅子市场趋于饱和,竞争的白热化和同质化带来了全行业的价格战,彼时西昊的经营陷入巨大的困境,所有的产品和钱都变成成库存,现金流几乎枯竭。因此,西…

文心一言《使用手册》,文心一言怎么用?

一、认识文心一言 (一)什么是文心一言 文心一言是百度研发的 人工智能大语言模型产品,能够通过上一句话,预测生成下一段话。 任何人都可以通过输入【指令】和文心一言进行对话互动、提出问题或要求,让文心一言高效地…

智能家居产品公司网站源码,自适应布局设计,带完整演示数据

适合各类智能家居电子产品使用的网站源码,深色大气设计,自适应布局设计,pc手机均可完美适配,带完整演示数据。 独家原创资源。源码是asp开发的,数据库是access,主流的虚拟主机空间都支持asp,直…

<Rust><GUI>rust语言GUI库tauri体验:前、后端结合创建一个窗口并修改其样式

前言 本文是rust语言下的GUI库:tauri来创建一个窗口的简单演示,主要说明一下,使用tauri这个库如何创建GUI以及如何添加部件、如何编写逻辑、如何修改风格等,所以,这也是一个专栏,将包括tauri库的多个方面。…

面对人工智能发展的伦理挑战:应对策略与未来方向

✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…

硬件开发笔记(二十六):AD21导入电感原理图库、封装库和3D模型

若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/140437290 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…

SAP ERP与金蝶云星空的集成案例(新能源光伏行业)

一、项目环境 阳光新能源开发股份有限公司(简称“阳光电源”)是一家专注于新能源开发利用的国家高新技术企业。作为阳光电源(股票代码:300274)旗下的新能源开发投资平台,阳光新能源聚焦光伏、风电、风光…

暴雨让服务器不怕热҈热҈热҈热҈

在AI算力呈几何倍数增长的趋势下,算力逐渐朝着“高性能、高密度、高耗能“发展。在高耗能的算力下,AI服务器功率已逐步逼近风冷散热极限,而液冷作为更加高效、低能耗的制冷技术,逐渐成为了高密度算力散热场景的首选方案。 液冷的…

数据结构-java中链表的存储原理及使用方式

目录 链表(线性表的链式存储) 代码实例:(链表构建,头插尾插) LinkedList LinkedList的使用: 1、构造方法 2、操作方法 LinkedList 和 ArrayList 的区别 链表(线性表的链式存储…

Minio搭建文件服务器的学习

MinIO是一个高性能的开源对象存储服务器,与Amazon S3兼容。它使用Go语言编写,可以在多种操作系统上运行,如Linux、MacOS和Windows等。MinIO的分布式特性使其能够轻松扩展存储容量和处理能力,满足大规模数据存储的需求。 使用Docke…

你也想做一个Element-ui吧!!!——Blueの前端路(一)

目录 前言: 父子组件 button组件 使用vue脚手架初始化一个项目 如何封装,注册和使用一个组件 main.js中将组件设置为全局 使用 此组件我们所需实现的内容 type 父组件组件传递type属性 子组件接收负组件传递的数据 通过绑定类名的方法动态控制…

北汽蓝谷:预期能否兑现

天天提热搜,公司却一路亏损,股价却一路走高,今天说说——北汽蓝谷 问最近车圈谁最热,北汽蓝谷少不了。先是享界S9上市定档,华为余承东“在线带货”。 后有百度无人驾驶萝卜快跑引发全网热议,所用车型便来自…

TF/SD卡开发驱动(SPI)

TF与SD卡本质上来说都是flash类型的存储器 可以理解为TF卡是SD卡的升级版,体积小功能强大,SD卡是传统意义上的存储卡,适用范围比较广,而SD卡的驱动方式有两种 SDIO 和 SPI,同理TF卡也是一样 (在资源足够…

2024黑马AI+若依框架项目开发 个人心得、踩坑和bug记录 全网最快最全 基础功能认识篇

2024黑马AI若依框架项目开发 个人心得、踩坑和bug记录 全网最快最全 基础功能认识篇 你好,我是Qiuner. 为帮助别人少走弯路和记录自己编程学习过程而写博客 这是我的 github https://github.com/Qiuner ⭐️ ​ gitee https://gitee.com/Qiuner 🌹 如果本篇文章帮到…

[web]-图片上传、文件包含-图片上传

题目内容提示:上传图片试试吧,注意统一时区问题 打开页面如图,源码没有过滤,随便输入,进入上传目录 根据链接可以看到是文件包含,可以利用编码读取源码,这里只列出有用页面的编码(?…

初识C++|类和对象(中)——类的默认成员函数

🍬 mooridy-CSDN博客 🧁C专栏(更新中!) 🍹初始C|类与对象(上)-CSDN博客 4. 类的默认成员函数 默认成员函数就是⽤⼾没有显式实现,编译器会⾃动⽣成的成员函数称为默认成…

测试开发面经总结(三)

TCP三次握手 TCP 是面向连接的协议,所以使用 TCP 前必须先建立连接,而建立连接是通过三次握手来进行的。 一开始,客户端和服务端都处于 CLOSE 状态。先是服务端主动监听某个端口,处于 LISTEN 状态 客户端会随机初始化序号&…