【MySQL】索引的作用及知识储备

为什么要有索引

索引可以提高数据库的性能。不用加内存,不用改程序,不用调sql,只要执行正确的create indix,查询的速度就可能提高成百上千倍。但相应的代价是,插入,更新,删除的速度有所减弱。

所以索引的作用在于提高一个海量数据的检索速度

常见索引分为:

  • 主键索引(primary key)
  • 唯一键索引(unique)
  • 普通索引(indix)
  • 全文索引(fulltext) - 解决子文索引问题

认识磁盘

我们知道了索引的作用是提高数据检索的速度,那么海量数据的检索为什么慢呢?我们需要通过认识数据的存储来了解

MySQL与存储

MySQL给用户提供存储服务,而存储的都是数据,数据在磁盘这个外设当中。磁盘是计算机中的一个机械设备,相比于其他电子元件,磁盘的效率是比较低的 ,在加上IO本身的特征,所以存取数据是一个比较慢的操作


磁盘的物理结构和数据存取可以参看磁盘文件系统的第一部分

总结来说

数据的存取在磁盘中需要经历以下步骤:

  1. 定位读取的盘面,进而确定哪一个磁头读取数据
  2. 定位读取哪一个磁道
  3. 定位读取哪一个扇区
    整个过程称为CHS定位法 磁头:head ;磁道(柱面):cylinder;扇区:sector
    这些步骤都是机械运动,所以速度相比于电子元件,会慢上很多

另外

数据在扇区里大多是以512字节存储

操作系统读取数据的单位是数据块(4kb),也就是8个扇区

数据库文件,本质就是保存在磁盘的盘片当中,当数据库文件很大时,一定需要占据多个扇区


磁盘随机访问与连续访问
  • 随机访问:本次IO所给出的扇区地址和上次IO给出的扇区地址不连续,此时磁头在两次IO操作之间需要作较大移动才能重新开始读/写数据
  • 连续访问:如果本次IO给出的扇区地址与上次IO结束的扇区地址是连续的,那么磁头就能很快的开始这次IO操作,这样的多个IO操作称为连续访问

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

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

MySQL与磁盘交互的基本单位

MySQL是一款应用软件,其与磁盘的交互需要依靠操作系统从中构建桥梁,我们可以将其想象为一种特殊的文件系统,它有着更高的IO场景。

所以为了提高基本的IO效率,MySQL进行IO的基本单位是16KB(InnoDB存储引擎)

sql 复制代码
mysql> show global status like 'innodb_page_size';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| Innodb_page_size | 16384 | -- 16*1024
+------------------+-------+

也就是磁盘 的基本单位是扇区512字节操作系统 基本单位是数据块4KBMySQL 基本单位是page(页)16KB

三者数据交互如下:

  • MySQL中的数据文件,是以page为单位保存在磁盘当中的
  • MySQL的CURD操作(create update read delete),都是需要计算,找到相应的插入位置,或者找到对应要修改或者查询的数据
  • 涉及计算,就需要CPU参与,而为了便于CPU参与,一定要能够先将数据移动到内存当中
  • 所以在特定时间内,数据一定是在磁盘和内存中都存在的。后续完成内存数据的操作后,以特定的舒心策略,刷新到磁盘。此时会涉及磁盘和内存的数据交互,也就是IO。而此时IO的基本单位是page
  • 为了更好的进行上述操作,MySQL服务器在内存运行时,在服务器内部,会申请被称为buffer bool的内存空间,来进行各种缓存。使用这个内存空间和磁盘数据进行IO交互
  • 所以为提高效率,一定要尽可能的减少系统和磁盘的IO次数

局部性原理

局部性原理分为时间局部性空间局部性

局部性原理出现的原因,大部分人认为是:程序的指令大部分时间是顺序执行 ,而且程序的集合,如数组等各种数据结构都是连续存放

  1. 时间局部性:如果程序中的某条指令 一旦执行,则不久之后该指令可能再次被执行 ;如果某数据 被访问,则不久之后该数据可能再次被访问
  2. 空间局部性:一旦程序访问了某个存储单元,则不久之后,其附近的存储单元也很大可能被访问

参考:局部性原理


MySQL的IO交互为什么要用page

为什么MySQL和磁盘进行IO交互要使用page呢?而不是用多少加载多少呢?

倘若,我们有十个数据,其中id从1到10,如果用多少加载多少,每次都只加载一个数据,查找id=10就需要十次IO

但如果使用page存储,那么十个数据都是存储在一个page中,一次IO读取整个page,放入buffer bool 。无论是id=3,4,8,都是在内存中查找。大大减少了IO的次数

但是我们无法保证,用户下次查找的数据一定在这个page中,但是因为局部性原理,大概率在这个page中
往往IO效率低下的最主要矛盾不是IO单次数据量的大小,而是IO的次数

相关推荐
爬山算法23 分钟前
Redis(69)Redis分布式锁的优点和缺点是什么?
数据库·redis·分布式
RestCloud26 分钟前
从数据库到价值:ETL 工具如何打通南大通用数据库与企业应用
数据库
惜月_treasure1 小时前
Text2SQL与工作流实现:让数据库查询变得轻松又高效
数据库·人工智能·python
-睡到自然醒~1 小时前
[go 面试] 并发与数据一致性:事务的保障
数据库·面试·golang
为乐ovo1 小时前
19.DCL-用户管理
数据库
可观测性用观测云1 小时前
阿里云 RDS MySQL 可观测性最佳实践
mysql
一个天蝎座 白勺 程序猿2 小时前
金仓数据库KingbaseES实现MongoDB平滑迁移全攻略:从架构适配到性能调优的完整实践
数据库·mongodb·数据迁移·kingbasees·金仓数据库
武子康2 小时前
Java-153 深入浅出 MongoDB 全面的适用场景分析与选型指南 场景应用指南
java·开发语言·数据库·mongodb·性能优化·系统架构·nosql
2401_837088502 小时前
Redis通用命令
数据库·redis·缓存
程序边界2 小时前
MongoDB迁移到KES实战全纪录(上):迁移准备与实施指南
数据库·mongodb