在 MySQL 中,联合索引(又称为复合索引)是由多个列组成的索引,它的使用遵循 最左前缀法则。理解这个法则可以帮助我们判断哪些查询条件能够使用到联合索引。
假设我们有一个三列的联合索引 (A, B, C)
,以下是各种查询条件是否会走索引的分析:
1. 完全匹配左边的列
-
WHERE A = ? AND B = ? AND C = ?
:能使用索引。因为完全匹配了索引的所有三列,能够充分利用联合索引。 -
WHERE A = ? AND B = ?
:能使用索引。匹配了索引的前两列A
和B
,因此可以走索引。 -
WHERE A = ?
:能使用索引。只匹配了索引的第一列A
,仍然可以走索引。
2. 跳过中间的列
-
WHERE B = ?
:不能使用索引。因为跳过了索引的第一列A
,违反了最左前缀法则。 -
WHERE A = ? AND C = ?
:能部分使用索引。MySQL 可以利用联合索引的第一列A
,但无法利用C
列。也就是说,索引只会在A
上起作用,C
则需要额外扫描。
3. 前缀匹配(范围查询)
-
WHERE A = ? AND B > ?
:能使用索引。因为范围查询B > ?
仍然符合最左前缀法则,因此索引可以被使用,但索引只能用于A
和B
,无法用于C
。 -
WHERE A = ? AND B = ? AND C > ?
:能使用索引。完全匹配了A
和B
,且C
是范围查询,因此可以走索引,且能利用C
。
4. LIKE
模糊查询
-
WHERE A = ? AND B LIKE 'abc%'
:能使用索引。因为LIKE
前面部分是常量,不是以通配符开头,所以索引可以用。 -
WHERE A = ? AND B LIKE '%abc'
:不能使用索引。因为LIKE
以%
开头,无法使用索引。
5. 只查询部分列
WHERE C = ?
:不能使用索引。因为跳过了前面的A
和B
列,违反了最左前缀法则。
总结:哪些组合能走索引?
WHERE A = ?
WHERE A = ? AND B = ?
WHERE A = ? AND B = ? AND C = ?
WHERE A = ? AND B > ?
WHERE A = ? AND B = ? AND C > ?
WHERE A = ? AND B LIKE 'abc%'
不能走索引的情况:
- 跳过前面的列,如
WHERE B = ?
或WHERE C = ?
。 LIKE
以%
开头的模糊查询,如WHERE A = ? AND B LIKE '%abc'
。
使用场景与业务应用
在业务场景中,联合索引可以用于优化频繁的多列查询场景,尤其是当查询条件匹配索引的前缀时。借助这个原理,你可以在以下场景中应用联合索引:
-
电商网站:联合索引
(category, brand, price)
可以加速基于商品类别和品牌的价格范围筛选。 -
日志查询系统:联合索引
(timestamp, user_id, action)
可以用于快速查找特定用户在某个时间段内的操作日志。
通过设计合理的联合索引,可以大大提高数据库的查询性能,尤其是涉及多列条件的复杂查询。
那么AC能走索引吗
在联合索引 (A, B, C)
的情况下,WHERE A = ? AND C = ?
能不能走索引是一个常见的问题。
AC能走索引的情况分析
根据 最左前缀法则,联合索引的使用要求必须从最左边的列开始匹配。这意味着,查询条件要利用索引,必须从索引的最左边第一列 A
开始。
场景:WHERE A = ? AND C = ?
- 在这个查询中,虽然
A
这一列是联合索引中的第一列,但B
这一列被跳过了。 - MySQL 无法跳过中间的列,因此它只能使用联合索引的第一列
A
进行查询,无法直接利用C
列。 - 结果是:这个查询 只能部分走索引。索引仅对
A
列有效,而C
列无法通过索引优化,C
列的条件将会在扫描A
列的结果后进行额外的过滤。
实际执行过程
- MySQL 会首先根据
A = ?
这一条件在联合索引中查找符合条件的所有记录。 - 查找到符合
A
的记录后,再对这些记录逐一检查C
的值,进行二次过滤。
因此,WHERE A = ? AND C = ?
在大部分情况下不能完全利用 (A, B, C)
这个联合索引,性能上不会得到全面优化。如果 A
过滤掉的记录不多,MySQL 可能需要扫描大量数据来处理 C
列,导致查询效率较低。
如何优化?
如果这种查询组合(A
和 C
)很常见,并且你希望优化这个场景,你可以考虑:
- 增加一个新的联合索引
(A, C)
,这样WHERE A = ? AND C = ?
的查询就可以完全利用这个新的联合索引。 - 拆分查询逻辑:先通过
A = ?
快速查找,获得主键后再使用主键去查询C
,这种方式可以在某些情况下提升性能。
总结:AC能否走索引?
WHERE A = ? AND C = ?
只能部分走索引。因为跳过了B
列,无法完全利用联合索引(A, B, C)
,MySQL 只会使用A
列的索引进行查询。- 如果你需要频繁使用
A
和C
组合查询,建议为A
和C
单独创建一个联合索引(A, C)
来优化这个场景。
使用场景
在许多业务场景中,设计联合索引时需要根据实际的查询模式来调整索引设计。例如,假设你的业务逻辑要求通过 A
和 C
来筛选数据,但 B
列不常用,设计 (A, C)
索引会比 (A, B, C)
更高效。