有这么一张表 t_user,id是主键、phone是也是主键,name、class是联合主键

ID NAME PHONE CLASS
1 张一 18688887777 一班
2 张二 18688887778 二班
3 张三 18688887779 三班

# 回表、索引覆盖

拿索引当条件查才行

在索引上查询,查到到之后不能直接返回行数据,需要去数据文件或另一个索引继续查才能获得select的数据,就叫回表

反之一次查询就返回select的内容了(例如select的内容在聚集索引或者同一个索引上查询),就叫索引覆盖

select * from t_name where id = 1;

如果是MyISAM的非聚集式索引,通过主键id查询到的结果是行地址,需要再去数据文件拿到全部的行数据,这就代表回表了

如果是InnoDB的聚集式索引,通过主键id查询到的结果直接带上整行数据了,不需要额外再查别的了,就说明索引覆盖了

如果在InnoDB上这么查询呢?

select * from t_name where phone = 18688887777;

因为聚集索引只有一个,phone这个索引就叫二级索引(也叫辅助索引),它就只能是非聚集索引了

mysql执行的过程就是通过phone查到了id,然后拿着id回表,再通过id返回整行数据

# 索引下推

索引下推是Mysql自动帮你做的一件事,原则上就是查询条件上有索引的条件,先按照索引查出来交集,再回表查,可以减少回表次数

也是Mysql5.6之后才有的

select * from t_name where name like '张%' and class like '一%'

如果不开启索引下推,那么需要让name字段like一下姓张的,回表把结果集都拿出来,再让class字段like一个‘一’开头的

开启的话,直接根据姓张的条件,返回name,class两个字段,先不回表,然后再把class字段like一下出个交集,再回表

想关闭的话

set optimizer_switch='index_condition_pushdown=off';