花拾录
← 返回知识库

MySQL 联合索引最左前缀原则:用执行计划验证哪些查询真的用上了索引

数据库AI2026/09/300 阅读0 评论

什么是联合索引的最左前缀原则

联合索引(复合索引)是指包含多个列的索引,例如 INDEX idx_a_b_c (a, b, c)。MySQL 在使用联合索引时,会遵循最左前缀原则:查询条件必须从索引的最左列开始,并且不能跳过中间的列,才能利用该索引。

简单说,索引 (a, b, c) 相当于建立了 (a)、(a, b)、(a, b, c) 三个索引,但不会单独为 (b) 或 (c) 建立索引。

如何用 EXPLAIN 验证索引使用情况

在查询前加上 EXPLAIN 关键字,MySQL 会返回执行计划。重点关注以下列:

  • key:实际使用的索引名称。如果为 NULL,表示未使用索引。
  • type:访问类型,常见值从优到劣:system > const > eq_ref > ref > range > index > ALL。ALL 表示全表扫描。
  • rows:预估需要扫描的行数,越小越好。
  • Extra:额外信息,如 Using index 表示覆盖索引,Using where 表示在存储引擎层过滤。

准备测试环境

创建一张示例表并插入数据:

CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(50),
  age INT,
  city VARCHAR(50),
  INDEX idx_name_age_city (name, age, city)
);

-- 插入若干测试数据
INSERT INTO users (name, age, city) VALUES
('Alice', 25, 'Beijing'),
('Bob', 30, 'Shanghai'),
('Charlie', 35, 'Guangzhou');

各种查询场景的执行计划分析

1. 使用全部索引列

EXPLAIN SELECT * FROM users WHERE name = 'Alice' AND age = 25 AND city = 'Beijing';

结果:key 为 idx_name_age_city,type 为 ref。✅ 完全使用索引。

2. 使用最左列

EXPLAIN SELECT * FROM users WHERE name = 'Alice';

结果:key 为 idx_name_age_city,type 为 ref。✅ 使用索引。

3. 使用最左两列

EXPLAIN SELECT * FROM users WHERE name = 'Alice' AND age = 25;

结果:key 为 idx_name_age_city,type 为 ref。✅ 使用索引。

4. 跳过最左列

EXPLAIN SELECT * FROM users WHERE age = 25 AND city = 'Beijing';

结果:key 为 NULL,type 为 ALL。❌ 未使用索引,全表扫描。

5. 使用最左列和第三列(跳过中间列)

EXPLAIN SELECT * FROM users WHERE name = 'Alice' AND city = 'Beijing';

结果:key 为 idx_name_age_city,type 为 ref,但 Extra 可能显示 Using index condition 或 Using where。✅ 能使用索引,但只能用到 name 列,city 列无法用于索引查找(可能用于过滤)。

6. 范围查询后的列失效

EXPLAIN SELECT * FROM users WHERE name = 'Alice' AND age > 20 AND city = 'Beijing';

结果:key 为 idx_name_age_city,type 为 range。✅ 使用索引,但 city 列无法用于索引查找,因为 age 是范围条件。

7. 最左列使用范围查询

EXPLAIN SELECT * FROM users WHERE name LIKE 'A%' AND age = 25;

结果:key 为 idx_name_age_city,type 为 range。✅ 使用索引,但 age 列无法用于索引查找。

8. 最左列使用函数或运算

EXPLAIN SELECT * FROM users WHERE UPPER(name) = 'ALICE';

结果:key 为 NULL,type 为 ALL。❌ 未使用索引,因为对索引列使用了函数。

总结与建议

  • 联合索引必须从最左列开始使用,否则无法利用索引。
  • 范围查询(>、<、BETWEEN、LIKE 前缀匹配)会导致其后的列无法用于索引查找。
  • 避免在索引列上使用函数或表达式,否则索引失效。
  • 设计联合索引时,将选择性高(区分度大)的列放在左边,但也要考虑最左前缀原则和实际查询模式。
  • 使用 EXPLAIN 验证实际查询是否命中索引,是优化 SQL 的必备步骤。

通过以上示例和 EXPLAIN 的输出,你可以清晰地判断哪些查询真正用上了索引,并据此调整索引设计或 SQL 写法。

评论(0)

  • 还没有评论,来抢沙发~

相关文章