Skip to content

MySQL 联合索引创建指南

约 653 字大约 2 分钟

关系型数据库

2025-07-25

实际的开发过程当中为 MySQL 建立联合索引是无法避免的。但是考虑到最左匹配原则和一些索引失效的场景,建立索引仍然存在一些技巧。本文将给出一些简单的场景,根据这些场景来讨论如何创建 MySQL 联合索引是最有效的。

WHERE a = 1 AND b = 2 AND c = 3

SELECT * FROM <table> WHERE a = 1 AND b = 2 AND c = 3;

可以注意到 WHERE 语句中的三个限制条件都是 =,不会引起索引的失效。所以建立 ( a, b, c ) 、 ( c, b, a ) 或者 ( b, a, c ) 三种联合索引都可以。重点要的是将区分度高的字段放在前面,区分度低的字段放后面。像性别、状态这种字段区分度就很低,我们一般放后面。

WHERE a > 1 AND b = 2

SELECT * FROM <table> WHERE a > 1 AND b = 2;

由于 > 会引起索引的失效,根据最左匹配原则,我们应该对 ( b, a ) 建立索引。如果你建立的是 ( a, b ) 索引,那么只有 a 字段能用得上索引,毕竟最左匹配原则遇到范围查询就停止匹配。

如果对 ( b, a ) 建立索引那么两个字段都能用上,优化器会帮我们调整 WHERE 后 a 和 b 的顺序,让我们用上索引。

WHERE a > 1 AND b = 2 AND c > 3

SELECT * FROM <table> WHERE a > 1 AND b = 2 AND c > 3;

跟上一个场景类似,这种情况下建立 ( b, a ) 或者 ( b, c ) 都可以。

WHERE a = 1 ORDER BY b

SELECT * FROM <table> WHERE a = 1 ORDER BY b;

此时应该对 ( a, b ) 建索引。因为这样在索引树中当 a = 1 的时候,b 相对有序,可以避免再次排序。

WHERE a > 1 ORDER BY b

SELECT * FROM <table> WHERE a > 1 ORDER BY b;

跟上一个场景不同的是,这一次 a 字段是范围查询,这个范围内 b 值是无序的。所以我们应该对 ( a ) 建立索引,没有必要对 ( a, b ) 建立索引。

WHERE a = 1 AND b = 2 AND c > 3 ORDER BY c

SELECT * FROM <table> WHERE a = 1 AND b = 2 AND c > 3 ORDER BY c;

这种场景下应该对 ( a, b, c ) 建立索引。c 字段也包含进去可以避免重新的排序。

WHERE a IN ( 1,2, 3 ) AND b > 1

SELECT * FROM <table> WHERE a IN ( 1,2, 3 ) AND b > 1;

对 ( a, b ) 建立索引。因为 IN 在这里可以视为等值引用,不会中止索引匹配。

贡献者

更新日志

2025/8/5 08:34
查看所有更新日志
  • eb6eb-improve(docs): use pangu formatter
  • 6bf5f-fix(docs): fix text typo
  • c0b7f-feat(docs): add new articles

Keep It Simple