<h2>前言</h2><br>要搞明白覆盖索引首先就得明白主键索引和辅助索引的区别,以及查询时引擎的工作方式。<br>当然,以上都是基于innoDB引擎来说。<br><h2>主键索引与辅助索引的区别</h2><br>相信大家也了解过这方面的知识,这里就不展开了,直接上总结。<br>主键索引<br>叶子节点保存数据<br>辅助索引<br>叶子节点保存主键值<br><h2>查询一条数据是如何工作的呢</h2><br>先说查询过程:<br>由于辅助索引只存储主键的值,如果使用辅助索引搜索数据就必须先从辅助索引取到主键的值,再使用主键的值去主键索引上查询,直到找到叶子节点上的数据返回。 ---- 这个也称之为回表<br>那么如何避免**回表**查询的发生呢?<br>如果辅助索引上已经存在我们需要的数据,那么引擎就不会去主键上去搜索数据了。 ---- 这个就是所谓的"**覆盖索引**"<br>接下来我们来证明一下它。<br><h2>回表查询</h2><br>假如有这样一张表:<br>CREATE TABLE `test` ( `id` int(11) NOT NULL, `age` int(11) NOT NULL, `name` varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `idx_age_name` (`age`,`name`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;<br>我们给age添加一个索引, 接下来随意插入几条数据<br>insert into test(`id`,`age`,`name`) VALUES(1,10,"小明"),(2,11,"小红"),(3,12,"小伟");<br>查询一条数据<br>select * from test where age = 10<br>查看一下耗时<br><img><br>分析一下语句:<br>desc select * from test where age = 10<br>查看执行计划:<br><img><br>可以看到extra列为空,key则使用了idx_age索引, 大致的查询耗时在0.024秒左右。<br>这样的查询速度快吗?<br>我说我还能再优化一下,你敢信吗? - 鲁迅(我没说过)<br><h2>覆盖索引</h2><br>只需要稍微改变一下查询的字段, 我们就发现其中的区别了。<br>select age,name from test where age = 10<br>查看一下耗时:<br><img><br>可以看到耗时减少了!<br>发生了什么呢,我们再来分析一下语句<br>desc select age,name from test where age = 10<br><img><br>可以看到extra列有一个 *using idnex* , 这个的意思就是使用了覆盖索引,无需回表查询了。<br><h2>总结</h2><br>