跳到正文
Elaine Blog
返回

联合索引、覆盖索引与索引下推

MyBatis、MySQL 与数据架构

联合索引不是把常用列随便放在一起。列顺序要服务具体查询:通常先处理等值条件,再考虑范围和排序,最后只在收益明确时加入少量返回列形成覆盖。

Table of contents

Open Table of contents

从一条查询开始

SELECT id, created_at
FROM orders
WHERE user_id = 1
  AND created_at >= '2026-01-01'
ORDER BY created_at, id
LIMIT 20;

实验索引是 (user_id, created_at, id)user_id 做等值定位,后续键仍按 created_at, id 有序,可以完成范围与排序;查询只返回索引已包含的列时,还可能覆盖读取。

最左前缀不是口诀

B+Tree 按整个复合键的字典序排列。没有约束第一列时,相同第二列散落在许多第一列分组中,所以通常无法像完整前缀那样连续定位。它是数据排列结果,不是数据库人为设置的神秘规则。

范围条件之后的列不一定完全“失效”:它们可能不能继续缩小索引起止区间,却仍可参与索引条件下推或排序判断。应以 EXPLAIN ANALYZE 为准。

覆盖与下推的区别

覆盖是“不要回表”,下推是“少回表”。二者都不是免费的:索引越宽,写入维护成本、占用空间和 Buffer Pool 压力越大。

一张查询—索引清单

每个候选索引都记录服务的 Top SQL、过滤列、排序列、预计选择性、写入频率、索引大小和可替代索引。发现一个宽索引能覆盖另一个窄索引时,也不要直接删除,先用不可见索引或测试环境观察计划变化。

下一步

继续阅读06-08 排序、分页、Join 与子查询优化,处理跨表和深分页问题。


分享这篇文章:

上一篇
Explain 与执行计划阅读
下一篇
排序、分页、Join 与子查询优化