联合索引必须严格遵循最左前缀匹配原则:where条件须从索引最左列开始连续等值匹配,user_id、tenant_id等高频必查字段必须置顶;范围查询(>、between等)会使右侧字段失效;order by/group by字段需紧接等值条件且顺序一致;验证须依赖explain的key、key_len、extra三项。

联合索引不是把WHERE里出现的字段随便堆一起就完事——顺序错了,90%的查询根本用不上。
WHERE条件里哪些字段必须放最左
索引只能从左到右连续匹配,user_id、tenant_id这类高频且必查的等值字段,必须放在最左。哪怕email区分度更高,只要它不总出现在WHERE开头,就不该抢第一位。
- 等值条件(
=、IN)才能作为“起点”,范围条件(>、BETWEEN)一旦出现,右侧字段全部失效 - 如果常查
WHERE status = ? AND created_at > ?,但status只有3个值,MySQL可能直接跳过索引——这时得补上更靠前的高选择性字段,比如tenant_id -
WHERE a = ? AND c = ?无法利用(a, b, c)索引中的c,因为b缺失,中间断了
范围查询是索引生效的分水岭
>、、<code>BETWEEN、LIKE 'abc%' 这些操作会让索引“停在这一列”,后面字段不再用于查找,只可能参与排序或覆盖。
-
INDEX (a, b, c)+WHERE a = 1 AND b > 2 AND c = 3→ 只用上a和b,c不走索引查找 - 想让
c也生效?得把c挪到b前面,或者确认b其实是IN(多个等值),MySQL会把它当作等值处理 -
LIKE '%abc'或LIKE '%abc%'会让整个索引前缀失效,别指望它走索引
ORDER BY 和 GROUP BY 字段要不要塞进联合索引
要,但不能硬塞到最左——它们得紧接在等值字段之后,且顺序、方向必须严格一致,否则Using filesort照旧。
-
INDEX (city, age, score)支持WHERE city = 'Beijing' ORDER BY age, score,不支持ORDER BY score单独出现 -
GROUP BY a, b要用索引加速,索引必须是(a, b)或(a, b, ...),且不能中间断开 - 如果
ORDER BY字段和WHERE字段顺序不一致(比如索引是(a,b),但写ORDER BY b,a),优化器不会重排,直接回退到文件排序
怎么验证索引到底有没有被用上
光看CREATE INDEX成功没用,得跑EXPLAIN盯三个关键字段:key、key_len、Extra。
-
key为空 → 没走索引;key有值但rows接近全表 → 索引没起效或选择性太差 -
key_len告诉你实际用了索引前几字节,比如key_len=8说明只用了前两个INT字段,第三个没命中 -
Extra里出现Using index才算真正覆盖;Using index condition表示用了ICP,但仍有回表;Using where; Using index是常见误导项,它只表示WHERE用了索引过滤,不等于覆盖
最容易被忽略的是:字段类型隐式转换会让整个索引失效,比如user_id是BIGINT,但查询传了字符串'123',MySQL自动转成数字时就放弃了索引。这种问题在线上往往静默发生,得靠EXPLAIN逐条比对参数类型才抓得住。











