温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

覆盖索引能减少扫描次数吗

发布时间:2026-07-14 18:11:22 来源:亿速云 阅读:96 作者:小樊 栏目:数据库

能,覆盖索引(Covering Index)可以显著减少扫描次数,也常能减少回表次数。

下面从原理和实际效果来解释。


一、什么是覆盖索引

覆盖索引是指:

一条 SQL 所需的所有字段,都包含在某个索引中,不需要再回表查询聚簇索引(如 InnoDB 的主键索引)。

例如:

CREATE INDEX idx_a_b ON t(a, b);

查询:

SELECT a, b FROM t WHERE a = 1;

a、b 都在索引里 → 索引覆盖查询


二、覆盖索引如何减少“扫描次数”

1️⃣ 减少回表(最主要)

InnoDB 中:

  • 普通二级索引

    • 先扫描二级索引
    • 再根据主键回表查询聚簇索引
    • 至少两次扫描
  • 覆盖索引

    • 二级索引中已包含所有需要的字段
    • 不需要回表
    • 只扫描一次索引

减少一次聚簇索引扫描


2️⃣ 减少“行扫描”而不是“页扫描”

覆盖索引通常带来的是:

  • ✅ 减少扫描的 行数
  • ✅ 减少随机 IO(回表是随机 IO)

但不是:

  • ❌ 改变 B+Tree 的层级扫描
  • ❌ 神奇地让扫描“变零”

3️⃣ 在优化器层面更优

MySQL 优化器在以下情况下会优先选择覆盖索引:

  • 不需要回表
  • 索引顺序更利于范围扫描
  • 代价估算更低

三、对比示例

❌ 非覆盖索引

SELECT * FROM orders WHERE user_id = 10;

INDEX(user_id)
→ 扫描 user_id 索引
→ 回表查询完整行

扫描次数 ≈ 2 次 / 行


✅ 覆盖索引

SELECT user_id, status FROM orders WHERE user_id = 10;

INDEX(user_id, status)

→ 扫描索引
→ 不需要回表

扫描次数 ≈ 1 次 / 行


四、对性能的实际影响

场景 是否有明显效果
大表、高并发 ✅ 非常明显
磁盘 IO 瓶颈 ✅ 明显
小表或全内存 ⚠️ 改善有限
只查主键 ✅ 天然覆盖

五、注意几个误区

❌ 覆盖索引 ≠ 不扫描

  • 仍然可能:
    • 全索引扫描
    • 范围扫描
  • 只是不回表

❌ 不是所有 SELECT * 都能覆盖

  • SELECT * 一般 无法覆盖
  • 除非索引包含所有字段(不现实)

六、一句话总结

覆盖索引通过避免回表,减少聚簇索引扫描次数和随机 IO,从而显著降低整体扫描成本。

如果你愿意,可以把你的 表结构 + SQL + 执行计划 发出来,我可以帮你判断是否已经用到覆盖索引。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI