覆盖索引的核心作用是让查询完全在索引中完成,不触碰数据页,直接解决回表带来的性能损耗;其原理是二级索引叶子节点存储索引列值和主键值,当SELECT、WHERE、ORDER BY或GROUP BY涉及的列全部被单个索引覆盖时,MySQL可直接从索引页读取全部数据,执行计划中Extra显示“Using index”即命中覆盖索引。
覆盖索引的核心作用,是让查询完全在索引中完成,不触碰数据页。它直接解决回表带来的性能损耗问题。
InnoDB 的二级索引叶子节点只存索引列值 + 主键值。如果 SELECT 的字段、WHERE 的条件列、ORDER BY 或 GROUP BY 用到的列,全部被一个索引包含,MySQL 就能直接从索引页读出全部所需内容。
SELECT user_id, order_status FROM orders WHERE user_id = 10
01,若存在 INDEX idx_user_status (user_id, order_status),就构成覆盖回表本质是“一次索引查找 + 一次主键查找”的组合动作,而主键查找在物理上往往是随机 I/O。
不是字段堆得越多越好,关键看查询模式是否稳定、写入压力是否可接受。
(a, b, c),再建 (a, b) 通常无必要;但 (a, b, c) 无法覆盖 SELECT a, c ORDER BY b
别只看有没有索引,要看执行时到底走没走通。
EXPLAIN FORMAT=TRADITIONAL 查看 key 和 Extra 字段ref 或 range,且 Extra 含 Using index,才是真覆盖SHOW PROFILE 或 Performance Schema 观察 Handler_read_next 和 Handler_read_rnd_next 的比值,后者高说明回表频繁