尽量使用覆盖索引,减少select。那么什么是覆盖索引呢?覆盖索引是指查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到。 现在有一张用户表 表数据 索引情况: 索引 接下来,我们来看一组SQL的执行计划,看看执行计划的差别,然后再来具体做一个解析。explainselectid,professionfromtbuserwhereprofession软件工程andage31andstatus0;explainselectid,profession,age,statusfromtbuserwhereprofession软件工程andage31andstatus0;explainselectid,profession,age,status,namefromtbuserwhereprofession软件工程andage31andstatus0;explainselectfromtbuserwhereprofession软件工程andage31andstatus0; 从上述的执行计划我们可以看到,这四条SQL语句的执行计划前面所有的指标都是一样的,看不出来差异。但是此时,我们主要关注的是后面的Extra,前面两天SQL的结果为UUsingI而后面两条SQL的结果为:Usingindexcondition。 UUsingIndex:查找使用了索引,但是需要的数据都在索引列中能找到,所以不需要回表查询数据 Usingindexcondition:查找使用了索引,但是需要回表查询数据 因为,在tbuser表中有一个联合索引idxuserproagesta,该索引关联了三个字段profession、age、status,而这个索引也是一个二级索引,所以叶子节点下面挂的是这一行的主键id。所以当我们查询返回的数据在id、profession、age、status之中,则直接走二级索引直接返回数据了。如果超出这个范围,就需要拿到主键id,再去扫描聚集索引,再获取额外的数据了,这个过程就是回表。而我们如果一直使用select查询返回所有字段值,很容易就会造成回表查询(除非是根据主键查询,此时只会扫描聚集索引)。 为了大家更清楚的理解,什么是覆盖索引,什么是回表查询,我们一起再来看下面的这组SQL的执行过程。 id是主键,是一个聚集索引。name字段建立了普通索引,是一个二级索引(辅助索引)。 B。执行SQL:selectfromtbuserwhereid2; 根据id查询,直接走聚集索引查询,一次索引扫描,直接返回数据,性能高。 C。执行SQL:seletid,namefromtbuserwherenameA 虽然是根据name字段查询,查询二级索引,但是由于查询返回在字段为id,name,在name的二级索引中,这两个值都是可以直接获取到的,因为覆盖索引,所以不需要回表查询,性能高。 D。执行SQL:seletid,name,genderfromtbuserwherenameA 由于在name的二级索引中,不包含gender,所以,需要两次索引扫描,也就是需要回表查询,性能相对较差一点。