覆盖索引指查询所需字段全部包含在索引中,避免回表;联合索引按最左前缀原则排序,高频等值列置左、范围查询列置右,二者协同设计以减少I/O、免排序、少回表。
覆盖索引和联合索引不是“选一个用”,而是根据查询模式协同设计的两种关键手段。真正提升性能的关键,在于让数据库尽量少读数据页、少回表、少排序——索引就是为这个目标服务的。
覆盖索引指:查询所需的所有字段,全部包含在索引的键列(或包含列)中,无需回表查聚簇索引。MySQL 的二级索引叶子节点存的是主键值,如果 SELECT 的列都在该索引里,引擎直接从索引树返回结果,跳过聚簇索引查找。
例如:
SELECT user_id, status FROM orders WHERE order_date > '2025-01-01';
若存在索引 INDEX idx_date_status (order_date, status),但没包含 user_id,则仍需回表取 user_id;若建为 INDEX idx_cover (order_date, status, user_id),就构成覆盖索引。
联合索引按定义顺序构建 B+ 树:先按第一列排序,相同时再按第二列,依此类推。因此,只有满足“连续且从左开始”的列条件,才能高效利用索引进行范围扫描或等值查找。
对于索引 INDEX idx_u_s_t (user_id, status, create_time):
别靠猜,看执行计划(EXPLAIN)+ 查询频率 + 数据分布。重点考虑三件事:
业务场景:运营后台查“某用户近30天已完成订单数及总金额”
SQL:
SELECT COUNT(*), SUM(amount) FROM orders
WHERE user_id = 123
AND status = 'completed'
AND create_time >= '2025-05-01';
最优索引:
INDEX idx_user_status_time_amt (user_id, status, create_time, amount)
说明: