MySQL——索引
目录
一、磁盘
1.1 在系统软件上,并不直接按照扇区进行IO交互:
1.2 磁盘随机访问与连续访问
1.3 建立共识
二、Page
三、InnoDB
四、MyISAM
五、普通索引
一、磁盘
我们在使用Linux,所看到的大部分目录或者文件,其实就是保存在硬盘当中的。(当然,有一些内存文件系统,如: proc , sys 之类,我们不考虑)
1.1 在系统软件上,并不直接按照扇区进行IO交互:
-
如果操作系统直接使用硬件提供的数据大小进行交互,那么系统的IO代码,就和硬件强相关,换言之,如果硬件发生变化,系统必须跟着变化
-
从目前来看,单次IO 512字节,还是太小了。IO单位小,意味着读取同样的数据内容,需要进行多次磁盘访问,会带来效率的降低。
-
之前学习文件系统,就是在磁盘的基本结构下建立的,文件系统读取基本单位,就不是扇区,而是数据块task_struct。
1.2 磁盘随机访问与连续访问
-
随机访问:本次IO所给出的扇区地址和上次IO给出扇区地址不连续,这样的话磁头在两次IO操作之间需要作比较大的移动动作才能重新开始读/写数据。
-
连续访问:如果当次IO给出的扇区地址与上次IO结束的扇区地址是连续的,那磁头就能很快的开始这次IO操作,这样的多个IO操作称为连续访问。
-
因此尽管相邻的两次IO操作在同一时刻发出,但如果它们的请求的扇区地址相差很大的话也只能称为随机访问,而非连续访问。
-
磁盘是通过机械运动进行寻址的,随机访问不需要过多的定位,故效率比较高。
1.3 建立共识
-
MySQL 中的数据文件,是以page为单位保存在磁盘当中的。
-
MySQL 的 CURD 操作,都需要通过计算,找到对应的插入位置,或者找到对应要修改或者查询的数据。而只要涉及计算,就需要CPU参与,而
为了便于CPU参与,一定要能够先将数据移动到内存当中
。 -
所以
在特定时间内,数据一定是磁盘中有,内存中也有。
后续操作完内存数据之后,以特定的刷新策略,刷新到磁盘。而这时,就涉及到磁盘和内存的数据交互,也就是IO了。而此时IO的基本单位就是Page。 -
为了更好的进行上面的操作, MySQL 服务器在内存中运行的时候,在服务器内部,就申请了被称为 Buffer Pool 的大内存空间,来进行各种缓存。其实就是很大的内存空间,来和磁盘数据进行IO交互。
-
为了更高的效率,一定要尽可能的减少系统和磁盘IO的次数
二、Page
每个page用双向链表连接起来,但是在page内部检索时还是线性的复杂度,这里在单个page中就会引入索引,以至于快速检索:
三、InnoDB
显然单个Page是不够用的,所以可以给page也加上索引(目录),就引入了目录页,目录页的本质也是页,普通页中存的数据是用户数据,而目录页中存的数据是普通页的地址:
这样一层层可以加目录页,直到顶层只有一个page,这就是B+树,:
综上,
- Page分为目录页和数据页。目录页只放各个下级Page的最小键值。
- 查找的时候,自定向下找,只需要加载部分目录页到内存,即可完成算法的整个查找过程,大大减少了IO次数
四、MyISAM
MyISAM使用的也是B+树,但是它将索引与数据分离开来,这种叫做非聚簇索引,而InnoDB不将索引与数据分离成为聚簇索引:
五、普通索引
以上建立索引的方式可能都是通过Primary Key
,但是如果没有主键,数据库也会自己建立索引,这种就叫做普通索引, InnoDB 的非主键索引中叶子节点并没有数据,而只有对应记录的key值:
通过辅助(普通)索引,找到目标记录,需要两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。这种过程,就叫做回表查询