📄 MySQL 🟡 进阶 ⏱ 9 分钟

🔗 联合索引 & 最左前缀 & 索引失效

联合索引为什么必须从左开始匹配?范围查询怎么中断?8 种让索引失效的坑一次排掉。

1

什么是联合索引

🔗 多列索引

联合索引(Composite Index)是在多个列上建立的索引。

MySQL 按索引定义时列的顺序,把这些列的值拼接后构建 B+ 树。

例如联合索引 (a, b, c) 相当于创建了三个索引:(a)、(a,b)、(a,b,c)。

🎯 核心:最左前缀原则

查询条件必须从索引的最左列开始匹配,才能有效使用索引。

MySQL 一直向右匹配,直到遇到范围查询(> < BETWEEN LIKE)就停止。

2

最左前缀匹配规则

SQL 条件能否走索引说明
WHERE a = 1✓ 使用第一列
WHERE a=1 AND b=2✓ 使用第一、二列
WHERE a=1 AND b=2 AND c=3✓ 全部用全索引
WHERE a=1 AND c=3△ 部分a 走索引,c 不走(跳过 b)
WHERE b = 2✗ 不使用跳过第一列
WHERE b=2 AND c=3✗ 不使用跳过第一列
🎬 最左前缀一看就懂(索引 a,b,c)
✅ a=1
从最左列 a 开始 → 走索引
✅ a=1 AND b=2 AND c=3
连续从左到右 → 全部走索引
❌ b=2
跳过第一列 a → 索引失效
△ a=1 AND c=3
a 走索引,c 跳过了 b → 不走索引
3

范围查询中断规则

⛔ 范围查询会中断

遇到 > < BETWEEN LIKE 这类范围查询,MySQL 就停止向右匹配,范围条件之后的列无法走索引。

所以尽量把范围条件放到联合索引的最后。

✅ IN 不中断

IN 和 = 不影响后续列——MySQL 会把 IN 优化成多个等值条件,所以 IN 后面的列还能走索引。

SQL 条件走索引情况
WHERE a > 1 AND b = 2a 走范围,b 不参与(a 范围后中断)
WHERE a=1 AND b > 2 AND c=3a、b 走(等值→范围),c 不走
WHERE a=1 AND b IN (2,3) AND c=4全部走(IN 优化为等值)
4

8 种让索引失效的坑

1️⃣
隐式类型转换

WHERE phone = 13500001111(字段是 varchar,传数字)→ 类型转换导致索引失效。要传字符串。

2️⃣
最左前缀不满足

联合索引 (a,b),却 WHERE b=... 跳过了 a → 失效。条件要从最左列开始。

3️⃣
LIKE 以 % 开头

WHERE name LIKE '%new' → 前导通配符无法利用索引;改成 'new%' 才能走。

4️⃣
OR 条件未全索引

WHERE id=1 OR name='x' → 若 name 没索引,OR 的其它列无法索引,整条失效。

5️⃣
索引列参与计算

WHERE salary > 1.1 * 1000 → 对索引列做运算会使索引失效;应把计算移到右侧或写死。

6️⃣
IS NOT NULL

WHERE id IS NOT NULL → 可能使索引失效(NOT NULL 无法用索引做等值定位)。

7️⃣
NOT IN / <> 操作

WHERE id NOT IN (1,2) 或 id <> 3 → 不等/取反操作通常无法走索引。

8️⃣
优化器选择

有时即使能用索引,优化器按成本模型判断全表扫描更划算(如查询量占比大)→ 主动不用。

5

设计要点

🎯
区分度高的列放前面

联合索引列顺序至关重要,通常把区分度高的列放最前。

⏹️
范围条件放最后

范围查询会中断后续列,尽量把 > < BETWEEN 放联合索引末尾。

🔗
一个索引覆盖多个场景

(a, b) 可覆盖 a 和 (a,b) 两种查询,合理设计能减少索引数量。

🐛
IN 和 = 是朋友

IN 被优化成等值,不影响后续列走索引,和范围查询行为不同。

一句话总结

联合索引按列顺序拼接构建 B+ 树,遵循最左前缀原则——查询必须从最左列开始连续匹配,(a,b,c) 相当于 (a)、(a,b)、(a,b,c) 三个索引。范围查询(> < BETWEEN)会中断后续列,但 IN 会优化成等值不影响。8 大失效坑:隐式类型转换、最左前缀不满足、LIKE %开头、OR 未全索引、索引列运算、IS NOT NULL、NOT IN/<>,、优化器选择。设计上区分度高的列放前、范围条件放后。

🎤 面试问答 · 口语化回答
联合索引和最左前缀是 MySQL 索引最核心的考点,面试官常出具体 SQL 让你判断:
面试官什么是联合索引?最左前缀原则是什么?
你

联合索引就是在多个列上建的索引,MySQL 按定义时列的顺序把这些列的值拼接后构建 B+ 树。最左前缀原则是说查询条件必须从索引的最左列开始连续匹配才能用索引,比如 (a,b,c) 相当于建了 (a)、(a,b)、(a,b,c) 三个索引,所以 WHERE a=1 能用,WHERE b=2 跳过第一列就不能用。而且遇到范围查询就停止向右匹配。

💡 加分点:能说出「(a,b,c) 相当于三个索引」这个点,比单纯背原则更显理解。
面试官联合索引 (a,b,c) 下,这些查询能不能走索引?a=1、b=2、a=1 AND c=3、a=1 AND b>2 AND c=3
你

a=1 能走,用第一列;b=2 不能走,跳过了最左列 a;a=1 AND c=3 是 a 走索引,但 c 跳过了 b 所以 c 不走;a=1 AND b>2 AND c=3 是 a 走等值、b 走范围,但遇到范围查询就中断,所以 c 不走。关键是最左前缀要连续,范围查询会中断后面的列。

💡 加分点:能逐个判断并讲出「范围中断」规则,说明你真正掌握了,不是背。这是面试高频加分点。
面试官什么情况索引会失效?
你

我总结几个高频的:隐式类型转换,比如 varchar 字段传数字;最左前缀不满足,联合索引跳过了最左列;LIKE 以 % 开头,前导通配符用不了索引;OR 条件里有没索引的列;对索引列做计算或函数;IS NOT NULL;NOT IN 或 <> 这类取反操作;还有可能是优化器判断全表扫描更划算主动不用索引。

💡 加分点:能把 8 种坑分类说出来(类型转换/前缀/通配符/OR/计算/取反),体现系统性,面试官会印象深刻。
📝 读完打卡 · 写下你的收获 读完了?来打卡吧
用一句话写下你从这篇学到的最大收获,检验自己是否真的懂了 👇
⏱ 00:00 🔥0分