在 MySQL 中,覆盖索引(Covering Index)指的是: 查询所需的数据可以完全从索引中获取,而无需回表读取数据行。
覆盖索引是否成立,取决于查询字段、索引结构以及执行计划。下面从原理和条件角度对覆盖索引的成立规则进行说明。
当一个查询满足以下条件时,即可称为覆盖索引:
查询所需要的所有列,都包含在同一个索引中。
示例表结构:
CREATE TABLE orders (
id BIGINT PRIMARY KEY,
user_id BIGINT,
status TINYINT,
amount DECIMAL(10,2),
create_time DATETIME,
INDEX idx_user_status (user_id, status)
);以下查询可以使用覆盖索引:
SELECT user_id, status
FROM orders
WHERE user_id = 1001
AND status = 1;原因是:
user_id, status
(user_id, status)
以下查询 不满足 覆盖索引条件:
SELECT user_id, status, amount
FROM orders
WHERE user_id = 1001
AND status = 1;原因是:
amount 不在索引 idx_user_status 中
amount
SELECT *
FROM orders
WHERE user_id = 1001
AND status = 1;即使查询条件命中了索引:
因此,SELECT * 无法使用覆盖索引。
在 InnoDB 中,二级索引的叶子节点会包含主键值。
这意味着:
SELECT id
FROM orders
WHERE user_id = 1001
AND status = 1;该查询 仍然可能使用覆盖索引,因为:
id 是主键
覆盖索引不仅与 SELECT 列有关,也与 WHERE 条件有关。
以下查询可以使用覆盖索引:
SELECT user_id
FROM orders
WHERE user_id = 1001
AND status = 1;但以下查询无法使用:
SELECT user_id
FROM orders
WHERE status = 1;原因是:
status 不是联合索引的最左列
在 EXPLAIN 结果中,覆盖索引通常会出现以下特征:
key 显示所使用的索引
Extra 字段包含 Using index
示例:
EXPLAIN
SELECT user_id, status
FROM orders
WHERE user_id = 1001
AND status = 1;若 Extra 中显示:
Using index表示查询结果完全来自索引。
覆盖索引之所以能够避免回表,原因在于:
这是一种结构层面的优化结果,而非额外的执行策略。
覆盖索引是否成立,可以归纳为以下几点:
SELECT * 会直接破坏覆盖索引
EXPLAIN 中的 Using index 是重要判断依据
覆盖索引不是“特殊索引类型”,而是查询与索引结构共同作用的结果
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。