目录
概念:
核心规则:
底层原理:
底层原因:
概念:
最左前缀匹配原则是复合索引(由多个列组成的索引)的核心使用规则,指查询必须从索引的最左列开始,并且不能跳过中间的列,才能充分利用索引的有序性。如果跳跃某一列,被跳过的那一列后面的字段索引会失效。
注意,是从索引的最左列开始,不是表的最左列开始,比如:
这张student表,我要为s_name、s_gen、s_dept_id这三个字段创建联合索引:
从表中可看到s_name是最左边的一列,然后是s_gen,最后是s_dept_id。但是我觉的根据MySQL 联合索引的创建标准,我想把s_dept_id设置为索引的最左列,然后是s_name,最后是s_gen:
高选择性的列(唯一值多、重复值少)应尽量靠左。但需权衡查询模式,例如即使
col2
选择性更高,如果查询总是先基于col1
筛选,仍应将col1
放在最左。
核心规则:
-
必须包含最左列 查询条件必须包含索引的最左列。例如,索引
(A, B, C)
的查询条件可以是A
、A+B
、A+B+C
,但不能是B
或C
。 -
不能跳过中间列 若跳过中间列,后续列的索引无法生效。例如,
A + C
会跳过B
,此时仅A
生效,C
需回表过滤。以下是示例:
查询条件包含索引的最左列(s_dept_id),并且不跳过中间列时:
查询条件不包含索引的最左列:
查询条件只包含索引的最左列:
查询条件不跳过中间列:
查询条件跳过中间列(s_name):
由此,也可以推测:s_dept_id字段索引长度为5,s_name字段索引长度为42(47 - 5),s_gen字段索引长度为9(56 - 47)。
底层原理:
联合索引在存储时,是按照索引列的顺序来构建B+树的,比如先按A排序,A相同的情况下按B排序,再按C排序。因此,如果查询条件没有从最左列开始,就无法利用这个有序的结构,只能进行全表扫描或者部分扫描。
范围查询(开区间/查询条件不带等值判断)后的列无法使用索引的情况:
遇到范围查询(> 、<)会截断后续列(s_name和s_gen都被截断了):
如果某一列使用范围查询(如 >
、<
、BETWEEN
),其后的列无法使用索引。例如:
-
✅ 有效:
WHERE A=1 AND B>2
(仅使用A, B
) -
❌ 无效:
WHERE A=1 AND B>2 AND C=3
(C
无法生效)
底层原因:
还是因为联合索引在存储时,是按照索引列的顺序来构建B+树的。比如WHERE A=1 AND B>2 AND C=3,这时候在索引中,A和B会被使用,但C可能不会被使用,因为B的范围查询导致C在索引中的顺序不再连续,无法有效利用。