前文我们讲解了索引失效的原则。已经索引要遵循最左前缀法则。
覆盖索引
原则: 尽量使用覆盖索引, 减少select *的使用。
那么什么是覆盖索引呢? 覆盖索引是指查询使用了索引,并 且需要返回的列,在该索引中已经全部能够找到 。
接下来,我们来看一组SQL的执行计划,看看执行计划的差别,然后再来具体做一个解析。
explain select id, profession from tb_user where profession = '软件工程' and age =
31 and status = '0' ;
explain select id,profession,age, status from tb_user where profession = '软件工程'
and age = 31 and status = '0' ;
explain select id,profession,age, status, name from tb_user where profession = '软件工程' and age = 31 and status = '0' ;
explain select * from tb_user where profession = '软件工程' and age = 31 and status
= '0';
这些sql主要的不同在于,select查询结果的不同
- 第一个sql:id,profession
- 第二个sql:id,profession,age,status
- 第三个sql:id,profession,age,status,name
- 第四个sql:
我们可以看出后两个Extra是null并不是前面两个的Using Index。
Extra含义Using Index查找使用了索引,但是需要的数据都在索引列中能找到,所以不需 要回表查询数据Null查找使用了索引,但是需要回表查询数据
- 因为,在tb_user表中有一个联合索引 idx_user_pro_age_sta,该索引关联了三个字段 profession、age、status,而这个索引也是一个二级索引,所以叶子节点下面挂的是这一行的主 键id。 所以当我们查询返回的数据在 id、profession、age、status 之中,则直接走二级索引 直接返回数据了。
- 如果超出这个范围,就需要拿到主键id,再去扫描聚集索引,再获取额外的数据 了,这个过程就是回表。 而我们如果一直使用select * 查询返回所有字段值,很容易就会造成回表 查询(除非是根据主键查询,此时只会扫描聚集索引)。
因此覆盖索引,就是建立的索引包含了,要查找的全部字段
聚集索引是主键建立的,数据中包含了一行的全部内容。
因此我们写sql语句和建立索引时,应该避免回表扫描带来的影响。
Original: https://blog.csdn.net/abc123mma/article/details/127817716
Author: 兜兜转转m
Title: MySQL进阶-覆盖索引
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/654644/
转载文章受原作者版权保护。转载请注明原作者出处!