加载中...

| MySQL EXPLAIN 标志 | Extra: Using index |
| PostgreSQL 对应特性 | Index-Only Scan(9.2+) |
| 核心收益 | 消除回表随机 I/O |
普通二级索引的叶节点只存储索引列的值和主键。当查询需要 SELECT name, email 而索引只包含 name 时,引擎找到 name 匹配的主键后还要再到聚簇索引里做一次随机读取(回表),才能取到 email。如果结果集有一万行,就要做一万次随机 I/O——这在机械硬盘时代是灾难级别的开销,即便在 SSD 上也相当可观。[1]
解决方案就是把查询里所有 SELECT 和 WHERE 涉及的列都放进同一个索引。在 MySQL 里 EXPLAIN 输出的 Extra 列显示 Using index 就表示命中了覆盖索引,不需要回表。
实际案例:分页列表查询 SELECT id, title, status FROM articles WHERE status = 1 ORDER BY created_at DESC LIMIT 20,建索引 (status, created_at, id, title) 即可覆盖全部列。但要注意:把过多列塞入索引会增大索引体积,写入时的维护成本也更高,需要在读写之间找平衡点。
PostgreSQL 在 9.2 版本才正式支持 Index-Only Scan,之前即使索引包含所有列也需要访问堆表来验证可见性(Visibility Map),9.2 之后通过 VM 标记减少了大量不必要的堆访问。

| MySQL EXPLAIN 标志 | Extra: Using index |
| PostgreSQL 对应特性 | Index-Only Scan(9.2+) |
| 核心收益 | 消除回表随机 I/O |
登录 后参与讨论
暂无讨论,来发表第一条评论吧