MySQL-最左前缀匹配原则

leard 发布于 2025-05-28 4 次阅读


是什么

最左前缀匹配原则指的是在使用联合索引时,查询条件必须从索引的最左侧开始匹配,如果一个联合索引包括多个列,则查询条件必须包含第一个列的条件,然后是第二个,以此类推。

为什么

联合索引在B+树中的排序方式按照“从左到右”的顺序,例如联合索引(A,B,C)会按照(A,B,C)的顺序在B+树中进行排序。MySQL在查询时会优先使用A作为匹配依据,然后依次使用B和C。因此联合索引能够从左到右依次高效匹配,跳过最左侧字段会导致无法利用该索引。

注意点

范围查询遇到(>、<),就是停止匹配,例如 where a>1, b=2, c=3; a可以用上索引,但是b和c因为a经过范围查询,得到的数据是无序的,因此无法利用索引;但是遇到(>=、<=、between、前缀like),不会停止匹配。因为这些查询包含一个等值,可以直接定位到具体数据,然后往后扫描即可。

MySQL8的一个查询优化

Skip Scan

CREATE TABLE `t1` (
  `f1` int NOT NULL AUTO_INCREMENT,
  `f2` int NOT NULL,
  `f3` int NOT NULL,
  PRIMARY KEY (`f1`),
  KEY `idx_f2_f3` (`f2`,`f3`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

INSERT INTO t1 (f2,f3) VALUES
  (1,1), (1,2), (1,3), (1,4), (1,5),
  (2,1), (2,2), (2,3), (2,4), (2,5);
INSERT INTO t1(f2,f3) SELECT f2, f3 + 5 FROM t1;
INSERT INTO t1(f2,f3) SELECT f2, f3 + 10 FROM t1;
INSERT INTO t1(f2,f3) SELECT f2, f3 + 20 FROM t1;
INSERT INTO t1(f2,f3) SELECT f2, f3 + 40 FROM t1;


where f3=1;

MySQL8之前进行查询是无法使用索引的,但是在MySQL8之后进行查询,语句用上了范围扫描。

这是因为查询前先统计了f2的数据,一共就1和2两个值。然后将f2=1和f2=2拼接进查询条件中,之后使用最左匹配原则使用索引进行查询。但是如果f2的基数过多、查询语句中有group by或者distinct、查询跨表就会使skip scan失效。