磁盘预读:

  • 磁盘跟内存在进行交互的时候,有一个最基本的逻辑单位,称之为页,

  • 也叫做datapage,页的大小跟操作系统相关,一般是4k或者8k,我们在进行数据读取的时候,一般会读取页的整数倍,

    • 例如:innodb存储引擎中每次默认读取16kb

索引

提高查询效率

  • 数据持久化存储在磁盘中,没有办法直接把全量的数据一次性读取到内存,因此需要进行分块读取,每次读取一部分
k:查询的列值
v:文件名,偏移量,当前行记录的长度

减少io量

减少io次数

  • 一个表可以创建多少个索引? 很多个
  • 一个索引对应一颗B+树,还是所有的索引对应一颗B+树? 一个索引对应一颗B+树
  • 我们知道在B+树的叶子节点中存储实际的数据,那么当一张表中存在多个索引的时候,数据存储几份? 1份
  • 如果是一份的话,那么其他索引的叶子节点存储什么信息呢? mysql的官方解释确实叫做primarykey,但是这个东西不能直接翻译成主键,有问题

聚簇、非聚簇索引

  • 在mysql的innodb存储引擎中,每一条记录的插入必须要跟某一个索引值绑定在一起,如果表中有主键,那么数据跟主键存储在一起,如果没有主键,那么会选择唯一键进行存储,如果没有唯一键,那么mysql会生成6字节的rowid进行存储
  • 也就是说:mysql的数据存储只有一份,那么跟数据绑定存储的索引称之为聚簇索引,而没有跟数据绑定存储的称之为非聚簇索引

  • id,name,age,gender:id主键,name普通索引id是聚簇,name是非聚簇

回表

id,name,age,gender,addressid主键,name普通索引

select * from table where name='zhangsan'; 查找过程:先根据name的值在name的B+树上查找与之匹配的记录,找到的值是id,然后根据id再去id的b+树上查找整个行记录,这个过程称之为回表

效率低,不推荐使用,很多情况下sql用到了索引但是查询慢就是回表的问题,应该尽量避免回表

索引覆盖

id,name,age,gender,addressid主键,name普通索引

select id,name,age from table where name='zhangsan'; 查找过程:直接根据name的值去name的B+树上找到与之匹配的记录即可,也就是说索引节点的信息中包含了所有要查询的列的时候,不需要进行回表查询,就叫做索引覆盖

索引覆盖效率高,推荐使用

最左匹配

id,name,age,gender,address
id主键,name,age组合索引

select * from table where name='zhangsan' and age =20;
select * from table where name='zhangsan' ;
select * from table where age =20;
select * from table where age =20 and name='zhangsan';(优化器会调整条件的顺序)