索引-最左匹配
在数据库索引中,最左匹配原则确实在遇到某些范围查询时会停止向右匹配,但对于 >=
、<=
、BETWEEN
和前缀匹配的 LIKE
,索引匹配可以继续使用后续列。以下是详细分析:
1. 最左匹配原则的核心规则
最左匹配原则要求查询条件从复合索引的最左侧列开始,且不能跳过中间列。例如,索引 (a, b, c)
:
- ✅ 有效使用索引的条件:
a=1
、a=1 AND b=2
、a=1 AND b>2 AND c=3
。 - ❌ 无效的条件:
b=2
(未指定a
)、a=1 AND c=3
(跳过b
)。
2. 范围查询对索引匹配的影响
当遇到范围查询时,其右侧的索引列可能无法被使用,但具体行为因操作符而异:
(1) 严格范围查询(如 >
、<
)
- 索引匹配停止:右侧列无法使用索引。
-- 索引使用情况:(a, b) SELECT * FROM table WHERE a=1 AND b>2 AND c=3;
(2) 闭合范围查询(如 >=
、<=
、BETWEEN
)
- 索引匹配可继续:MySQL 优化器可能将闭合范围转换为等值查询+范围查询的组合,允许后续列使用索引。
-- 索引使用情况:(a, b, c) SELECT * FROM table WHERE a=1 AND b>=2 AND c=3;
(3) 前缀匹配的 LIKE
(如 LIKE 'abc%'
)
- 索引匹配可继续:前缀匹配被视为范围查询(类似
>= 'abc' AND < 'abd'
),右侧列仍可能使用索引。-- 索引使用情况:(a, b, c) SELECT * FROM table WHERE a=1 AND b LIKE '2%' AND c=3;
3. 示例验证
以索引 (a, b, c)
为例,通过 EXPLAIN
分析:
场景 1:使用 >
EXPLAIN SELECT * FROM table WHERE a=1 AND b>2 AND c=3;
- 结果:
key_len
仅覆盖a
和b
,c
未被使用。
场景 2:使用 >=
EXPLAIN SELECT * FROM table WHERE a=1 AND b>=2 AND c=3;
- 结果:
key_len
覆盖a
、b
和c
(若优化器将b>=2
转换为b=2 OR b>2
)。
场景 3:使用 BETWEEN
EXPLAIN SELECT * FROM table WHERE a=1 AND b BETWEEN 2 AND 5 AND c=3;
- 结果:
BETWEEN
被优化为b>=2 AND b<=5
,可能继续使用c
。
场景 4:使用 LIKE '2%'
EXPLAIN SELECT * FROM table WHERE a=1 AND b LIKE '2%' AND c=3;
- 结果:前缀匹配触发范围查询,
c
仍可能被索引覆盖。
4. 原理与优化器行为
- 闭合范围的优化:
>=
、<=
、BETWEEN
可能被拆分为等值查询和范围查询的组合,允许后续列使用索引。 - 前缀匹配的本质:
LIKE 'abc%'
被转换为>= 'abc' AND < 'abd'
,视为范围查询但允许继续匹配右侧列。
5. 总结与建议
操作符类型 | 是否停止后续索引匹配 | 示例 |
---|---|---|
严格范围查询(> 、< ) | ✅ 停止 | a=1 AND b>2 AND c=3 |
闭合范围查询(>= 、<= 、BETWEEN ) | ❌ 不停止(可能继续) | a=1 AND b>=2 AND c=3 |
前缀匹配(LIKE 'abc%' ) | ❌ 不停止 | a=1 AND b LIKE '2%' AND c=3 |
建议:
- 优先使用
>=
、<=
替代>
、<
,以最大化索引覆盖。 - 合理设计索引顺序,将等值查询列放在范围查询列左侧。
- 通过
EXPLAIN
验证实际执行计划,避免假设优化器行为。