一、定义
覆盖索引是指查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到。
二、例子
1. id为主键,默认是主键索引。
2. name字段为普通索引。
select * from tb_user where id = 1 覆盖索引
select id,name from tb_user where name = 'Arm' 覆盖索引
select id,name,gender from tb_user where name = 'Arm' 非覆盖索引(需要回表查询)
三、解释
1. 可以根据聚集索引和辅助索引找到的就是覆盖索引。
2. 而第三条sql里面的gender字段并不在辅助索引里面,需要根据id进行回表查询才能查到gender字段,所以这就不是覆盖查询。
四、解决MYSQL超大分页处理
在数据量比较大时,如果进行limit分页查询,在查询时,越往后,分页查询效率越低。因为,当在进行分页查询时,如果执行 limit 9000000,10 ,此时需要MySQL排序前9000010 记录,仅仅返回 9000000 - 9000010 的记录,其他记录丢弃,查询排序的代价非常大 。
优化思路: 一般分页查询时,通过创建 覆盖索引 能够比较好地提高性能,可以通过覆盖索引加子查询形式进行优化。
五、面试的回答
面试官:知道什么叫覆盖索引嘛 ?
候选人:覆盖索引是指select查询语句使用了索引,在返回的列,必须在索引中全部能够找到,如果我们使用id查询,它会直接走聚集索引查询,一次索引扫描,直接返回数据,性能高。
如果按照二级索引查询数据的时候,返回的列中没有创建索引,有可能会触发回表查询,尽量避免使用select *,尽量在返回的列中都包含添加索引的字段。
面试官:MYSQL超大分页怎么处理 ?
候选人:嗯,超大分页一般都是在数据量比较大时,我们使用了limit分页查询,并且需要对数据进行排序,这个时候效率就很低,我们可以采用覆盖索引和子查询来解决。
先分页查询数据的id字段,确定了id之后,再用子查询来过滤,只查询这个id列表中的数据就可以了,因为查询id的时候,走的覆盖索引,所以效率可以提升很多。