本章只讲mysql的内容
在理解回表之前需要先了解聚集索引和非聚集索引的区别
聚集索引
表数据和索引在同一个位置是聚集索引,一般主键是聚集索引,如果没有主键用唯一键,如果主键和唯一键都没有用rowid
非聚集索引
表数据和索引不在同一个位置
回表
举个例子
create table mytable(id int primary,name varchar,age int ,gender int);
alter table mytable add index index_1(name)
当前表中有2个索引:id是主键索引,name是普通索引
主键索引中维护了表的数据,普通索引中保存了id
select * from mytable where name = ?
因为用的是普通索引,索引查到id后还需要到主键索引中通过id再查一次
这种从非聚集索引跳转到聚集索引中查找数据的过程叫做回表
索引覆盖
先看这个查询语句
select id,name from mytable where name = ?;
因为name索引上有保存了name和id的信息,所以这里只用到普通索引就可以满足查询需求。
这种非聚集索引的叶子节点中包含了非聚集索引所需要的所有字段时,不需要回表,这就是索引覆盖
最左匹配
先创建一个联合索引
alter table mytable add index index_2(name,age)
索引使用的时候一定是从右到左来使用的,好比地区里的 省-市-区 概念,只有选到了省才可以选择市。
看几条查询语句
- select * from mytable where name =? and age =?;
- select * from mytable where name=?
- select * from mytable where age=?
- select * from mytable where age=? and name=?
1肯定是满足最左匹配的
2只有name 也是满足的
3没有name就想查age 好比不选省就选市,显然不可能
4从语句上看好像是先选age 再选name ,好像不满足,但是sql的优化器会帮你把顺序调整一下,所以它也是满足最左匹配的
还有一个隐藏点,如果你定义的一个索引包含了所以字段,那么无论你怎么写查询条件,都是满足索引的
索引下推
select * from mytable where name =? and age =?
在没有索引下推之前,执行的过程是:先根据name从存储引擎中拉去数据,然后根据age在service中过滤
有索引下推后,执行过程:根据name和age从存储引擎中过滤数据并拉去,不在service中做操作