联合索引生效关键在于最左前缀原则:必须从定义的最左列开始连续匹配,否则右侧字段失效;如索引(name,age,sex),where name='张三' and age>20时name和age有效,sex失效。

联合索引不是把几个字段堆在一起就行,关键在“怎么排”和“怎么用”。最左前缀原则就是它的使用铁律:MySQL只能从索引定义的最左边列开始,连续、不跳过地匹配查询条件,一旦中断,右边的列就失效。
为什么必须从最左列开始?
B+树索引是按联合索引字段顺序整体排序的——先按第一列升序,该列相同时再按第二列升序,依此类推。这意味着:
- 第一列在整个索引中全局有序,数据库能快速定位起始位置
- 第二列只在第一列值相同的数据块内有序,单独查它无法确定范围
- 第三列更受限,只在前两列都相同的子块里有序
比如索引是 (name, age, sex),若只写 WHERE age = 25,数据库根本不知道从哪棵子树开始找,只能全表扫描。
哪些查询能真正用上联合索引?
只要满足“连续、从左起”,就能逐级利用索引:
-
WHERE name = '张三'→ 用到 name -
WHERE name = '张三' AND age = 25→ 用到 name、age -
WHERE name = '张三' AND age = 25 AND sex = '男'→ 全部三列生效 -
WHERE name = '张三' AND age > 20→ name 和 age有效,sex因范围查询中断而失效 -
WHERE name = '张三' ORDER BY age→ name用于过滤,age天然有序,避免额外排序
哪些情况会让索引“形同虚设”?
常见三类断点,一踩就失效:
-
跳过中间列:如
WHERE name = '张三' AND sex = '男'(缺 age),只有 name 生效 -
不从最左开始:如
WHERE age = 25或WHERE age = 25 AND sex = '男',完全不走索引 -
前导模糊匹配:如
WHERE name LIKE '%三',破坏排序前提;而WHERE name LIKE '张%'是有效的
字段顺序怎么排才合理?
不能光看单个字段区分度高低,得结合真实查询模式:
- 高频等值条件优先靠左,比如常查
status = 'paid',就把 status 放第一位 - 范围查询字段(
>、、<code>BETWEEN、LIKE 'xxx%')尽量靠右,避免过早中断 - 常用排序或分组字段,可接在等值列之后,例如
WHERE status = ? ORDER BY create_time,适合建 (status, create_time) - 字段数建议控制在 3 个以内,兼顾查询效率与写入开销
最终是否生效,一定要用 EXPLAIN 看 key_len 和 type 字段验证,别凭经验猜。










