概述

一个索引包含了所有需要查询的字段值,那么就称为覆盖索引。

好处

  • 索引的大小通常远小于数据行大小,所以如果只需要读取索引,那么MySQL会极大的减少数据访问量。
  • 索引是按照值得顺序存储的。
  • InnoDB使用聚集索引,也称为First Index,InnoDB的二级索引叶子节点中保存了行的主键值,所以如果二级索引能够覆盖查询,那么可以避免对主键索引的二次查询。

并不是所有类型的索引都是称为覆盖索引。覆盖索引必须要存储列的值,所以哈希索引、空间索引和全文索引这三类不存储列值得索引都不能作为覆盖索引,所以MySQL中只能使用B+tree索引可以做覆盖索引

1.png

当查询使用了覆盖索引,可以在EXPLAIN的Extra列看到"Using index"的信息。

实验

基于MySQL 8.0.x
表结构和索引情况:

MySQL [employees]> desc sys_user;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int          | NO   | PRI | NULL    | auto_increment |
| name        | varchar(10)  | NO   |     | NULL    |                |
| name_pinyin | varchar(255) | NO   |     | NULL    |                |
| id_card     | varchar(255) | NO   | UNI | NULL    |                |
| phone       | varchar(20)  | YES  | MUL | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
5 rows in set (0.07 sec)

MySQL [employees]> show indexes from sys_user;
+----------+------------+-----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------------------+---------+------------+
| Table    | Non_unique | Key_name        | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment             | Visible | Expression |
+----------+------------+-----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------------------+---------+------------+
| sys_user |          0 | PRIMARY         |            1 | id          | A         |        3494 |     NULL |   NULL |      | BTREE      |         |                           | YES     | NULL       |
| sys_user |          0 | uni_idx_id_card |            1 | id_card     | A         |        3494 |     NULL |   NULL |      | BTREE      |         | 唯一索引-身份证号         | YES     | NULL       |
| sys_user |          1 | idx_phone_name  |            1 | phone       | A         |        3493 |     NULL |   NULL | YES  | BTREE      |         | 普通索引-手机号           | YES     | NULL       |
| sys_user |          1 | idx_phone_name  |            2 | name        | A         |        3493 |     NULL |   NULL |      | BTREE      |         | 普通索引-手机号           | YES     | NULL       |
+----------+------------+-----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------------------+---------+------------+
4 rows in set (1.54 sec)

覆盖索引查询

  1. 从sys_user表中查询手机号和姓名
explain select phone,name from sys_user;

EXPLAIN 输出结果:

MySQL [employees]> explain select phone,name from sys_user;
+----+-------------+----------+------------+-------+---------------+----------------+---------+------+------+----------+-------------+
| id | select_type | table    | partitions | type  | possible_keys | key            | key_len | ref  | rows | filtered | Extra       |
+----+-------------+----------+------------+-------+---------------+----------------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | sys_user | NULL       | index | NULL          | idx_phone_name | 125     | NULL | 3494 |   100.00 | Using index |
+----+-------------+----------+------------+-------+---------------+----------------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

  1. 从sys_user表中查询phone,name和id
explain select id, phone,name from sys_user;

EXPLAIN结果输出:

MySQL [employees]> explain select id, phone,name from sys_user;
+----+-------------+----------+------------+-------+---------------+----------------+---------+------+------+----------+-------------+
| id | select_type | table    | partitions | type  | possible_keys | key            | key_len | ref  | rows | filtered | Extra       |
+----+-------------+----------+------------+-------+---------------+----------------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | sys_user | NULL       | index | NULL          | idx_phone_name | 125     | NULL | 3494 |   100.00 | Using index |
+----+-------------+----------+------------+-------+---------------+----------------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

参考

  1. 高性能MySQL(第三版)
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐