磁盘预读:
磁盘跟内存在进行交互的时候,有一个最基本的逻辑单位,称之为页,
也叫做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,address
id主键,name普通索引
select * from table where name='zhangsan';
查找过程:先根据name的值在name的B+树上查找与之匹配的记录,找到的值是id,然后根据id再去id的b+树上查找整个行记录,这个过程称之为回表
效率低,不推荐使用,很多情况下sql用到了索引但是查询慢就是回表的问题,应该尽量避免回表
索引覆盖
id,name,age,gender,address
id主键,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';(优化器会调整条件的顺序)