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/7/28 02:58
查看所有更新日志
  • 6bf5f-fix(docs): fix text typo
  • c0b7f-feat(docs): add new articles

Keep It Simple