什么是覆盖索引

创建一个索引,该索引包含查询中用到的所有字段,称为“覆盖索引”。

使用覆盖索引,MySQL 只需要通过索引就可以查找和返回查询所需要的数据,而不必在使用索引处理数据之后再进行回表操作。

覆盖索引可以一次性完成查询工作,有效减少IO,提高查询效率。

也就是说,查询的列和索引的列一致,可以使用覆盖索引,查询中应该尽量使用覆盖索引,减少使用 select * from

使用示例1

查询语句:

SELECT col2, col3 FROM test_table WHERE col1 = xxx ORDER BY col2;

创建一个单列索引:

ALTER TABLE `test_table` ADD INDEX `idx_col1`(`col1`) USING BTREE;

分析查询:

EXPLAIN SELECT SQL_NO_CACHE col2, col3 FROM test_table WHERE col1 = xxx ORDER BY col2;

结果:对 col1 建立索引后,type 为 ref,使用到了 idx_col1 索引。


修改索引,根据查询语句,建立一个联合索引:

ALTER TABLE `test_table` DROP INDEX `idx_col1`;
ALTER TABLE `test_table` ADD INDEX `idx_col1_col2_col3`(`col1`,`col2`,`col3`) USING BTREE;

分析查询:

EXPLAIN SELECT SQL_NO_CACHE col2, col3 FROM test_table WHERE col1 = xxx ORDER BY col2;

结果:建立联合索引后,type 为 ref,使用了 idx_col1_col2_col3 索引,Extra 为 Using index,说明使用了覆盖索引。

使用示例2

创建索引:

ALTER TABLE `staffs` ADD INDEX idx_staffs_nameAgePos(`name`, `age`, `pos`);

使用覆盖索引查询:

EXPLAIN SELECT `name`,age,pos FROM staffs WHERE `name`='July' AND age=25 AND pos='dev';

1611477197365.png

以下这些查询也可以使用覆盖索引:

-- 范围查询
EXPLAIN SELECT `name`,age,pos FROM staffs WHERE `name`='July' AND age>25 AND pos='dev';
-- 查询条件中使用部分字段
EXPLAIN SELECT `name`,age,pos FROM staffs WHERE `name`='July' AND age=25;
-- 查询列中使用部分字段
EXPLAIN SELECT `name` FROM staffs WHERE `name`='July' AND age=25;

小伍
139 声望4 粉丝