MySQL——索引

时间:2024-11-04 16:10:27

目录

一、磁盘

1.1 在系统软件上,并不直接按照扇区进行IO交互:

1.2 磁盘随机访问与连续访问

1.3 建立共识

二、Page

三、InnoDB

四、MyISAM

五、普通索引


一、磁盘

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

1.1 在系统软件上,并不直接按照扇区进行IO交互:

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

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

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

1.2 磁盘随机访问与连续访问

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

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

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

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

1.3 建立共识

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

  2. MySQL 的 CURD 操作,都需要通过计算,找到对应的插入位置,或者找到对应要修改或者查询的数据。而只要涉及计算,就需要CPU参与,而为了便于CPU参与,一定要能够先将数据移动到内存当中

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

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

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

二、Page

每个page用双向链表连接起来,但是在page内部检索时还是线性的复杂度,这里在单个page中就会引入索引,以至于快速检索:

三、InnoDB

显然单个Page是不够用的,所以可以给page也加上索引(目录),就引入了目录页,目录页的本质也是页,普通页中存的数据是用户数据,而目录页中存的数据是普通页的地址

这样一层层可以加目录页,直到顶层只有一个page,这就是B+树,:


综上,

  • Page分为目录页和数据页。目录页只放各个下级Page的最小键值。
  • 查找的时候,自定向下找,只需要加载部分目录页到内存,即可完成算法的整个查找过程,大大减少了IO次数

四、MyISAM

MyISAM使用的也是B+树,但是它将索引与数据分离开来,这种叫做非聚簇索引,而InnoDB不将索引与数据分离成为聚簇索引

五、普通索引

以上建立索引的方式可能都是通过Primary Key,但是如果没有主键,数据库也会自己建立索引,这种就叫做普通索引, InnoDB 的非主键索引中叶子节点并没有数据,而只有对应记录的key值:

标题InnoDB普通索引(以col3为例)
标MyISAM普通索引(以col2为例)题

通过辅助(普通)索引,找到目标记录,需要两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。这种过程,就叫做回表查询