根本原因是索引未“兜住”查询路径;需按最左前缀原则建复合索引,等值字段置左、范围字段居中、排序字段靠右,并确保SELECT字段全被索引覆盖以避免回表。

为什么加了索引查询还是慢
根本原因不是没建索引,而是索引没“兜住”实际查询路径。比如 WHERE created_at > '2025-01-01' 却只在 user_id 上建了单列索引,EXPLAIN 里 type 仍是 ALL,等于白建。MySQL 只能用上复合索引的最左连续前缀,跳过开头字段就失效。
常见错误现象:
-
EXPLAIN中Extra显示Using where; Using filesort:ORDER BY 字段不在索引后缀里,被迫二次排序 -
rows预估值和实际扫描行数差距极大:统计信息过期,执行计划跑偏 - 明明写了
WHERE status = 1 AND user_id = 1001,却只走了status索引,过滤后仍扫十几万行:优化器误判选择性
复合索引字段顺序怎么排才对
顺序不是凭感觉,得按查询中各条件的“使用强度”来排:等值过滤字段放最左,范围查询字段居中,ORDER BY / GROUP BY 字段接在后面且保持顺序一致。
例如常跑这句:
SELECT order_id, amount FROM orders WHERE user_id = 1001 AND status = 'shipped' ORDER BY create_time DESC LIMIT 20;
对应建索引应为:
CREATE INDEX idx_user_status_time ON orders(user_id, status, create_time);
这样三个条件全被索引覆盖,EXPLAIN 的 Extra 才会显示 Using index(覆盖索引生效)。
容易踩的坑:
- 把
create_time放最左:导致WHERE user_id = ?完全无法走索引 - 在索引里塞
TEXT或超长VARCHAR字段:索引体积暴涨,写入变慢,B+树层级升高 - 忽略隐式类型转换:
user_id是INT,却传字符串'1001',索引直接失效
覆盖索引到底怎么判断是否生效
覆盖索引生效的唯一硬指标是:EXPLAIN 输出中 Extra 列出现 Using index,且你 SELECT 的所有字段都落在同一个索引定义内——不包括主键以外的未索引列。
比如表有 id(主键)、user_id、status、amount、remark(TEXT),你只查:
SELECT user_id, status, amount FROM orders WHERE user_id = 1001 AND status = 1;
那就建:
CREATE INDEX idx_uid_status_amount ON orders(user_id, status, amount);
注意 amount 放最后:它不参与过滤,只用于覆盖,放前面会浪费索引空间,还拖慢 INSERT/UPDATE。
关键限制:
-
SELECT *永远不可能走覆盖索引,因为*必然包含未索引字段 - 哪怕只多选一个没进索引的字段,比如
SELECT user_id, status, amount, remark,就会触发回表,Extra变成Using where - 索引下推(ICP)在 MySQL 5.6+ 默认开启,但只对索引字段有效;
remark这种非索引字段的过滤仍得回表后做
哪些查询场景必须放弃单列索引
当 WHERE 条件含两个及以上字段组合时,多个单列索引基本无效。MySQL 优化器通常只选一个(预估 rows 最小的那个),其余条件靠扫描过滤,性能和没索引差不多。
典型场景:
- 分页列表:如
WHERE category = 'book' AND is_published = 1 ORDER BY sort_order DESC LIMIT 20 - 后台筛选:如
WHERE start_time BETWEEN ? AND ? AND region IN ('bj', 'sh') AND status != 'draft' - 关联查询驱动条件:如
JOIN users u ON o.user_id = u.id WHERE u.status = 1 AND u.created_at > '2024-01-01'
这时候必须建复合索引,把高频等值字段放最左,范围字段居中,排序字段靠右。别指望优化器自动合并单列索引——它不会。
真正容易被忽略的是:索引不是越多越好。每多一个索引,INSERT/UPDATE/DELETE 就多一次 B+ 树维护开销,写入延迟可能增加 5%–10%。某社交平台曾因冗余索引过多,导致高峰期写入延迟飙升 300ms,最终删掉 23 个无用索引才恢复。


















