MySQL 查询索引最左前缀原则,如果是(a,b)的联合索引,WHERE b = ? AND a = ?会走索引吗

从SQL原本的理解上,不会走联合索引

但是MySQL有优化器,会针对 WHERE b = ? AND a = ? 这种特定情况进行优化,使其走联合索引(a,b)

  • 优化器的版本要求 MySQL >= 5.7
  • 如果其中有唯一索引,比如a是唯一索引,这里就不会走联合索引了,会走唯一索引,这样更快

在 MySQL 中,联合索引 (a, b) 的查询顺序必须遵循"最左前缀原则" 。如果查询条件是 WHERE b = ? AND a = ?,虽然逻辑上等价于 WHERE a = ? AND b = ?,但能否利用联合索引取决于实际书写顺序和优化器的处理。以下是详细分析:


1. 联合索引 (a, b) 的存储结构

  • 索引是按照 (a, b) 的顺序存储的,即先按 a 排序,a 相同的情况下再按 b 排序。
  • 最左前缀原则:查询必须从索引的最左列开始,才能有效利用索引。

2. WHERE b = ? AND a = ? 的情况

(1) 能否利用索引?

  • 严格来说,不能直接利用 (a, b) 索引 ,因为查询条件没有从 a 开始。
  • 但 MySQL 优化器可能会自动重写条件
    • 如果优化器将 WHERE b = ? AND a = ? 重写为 WHERE a = ? AND b = ?,则可以利用索引。
    • 如果未重写,则无法利用索引,可能导致全表扫描。

(2) 实验验证

表结构与索引
复制代码

sql

复制代码
`CREATE TABLE test (
    id INT PRIMARY KEY,
    a INT,
    b INT,
    INDEX idx_a_b (a, b)
);`
查询 1:WHERE a = 1 AND b = 2(符合最左前缀)
复制代码

sql

复制代码
`EXPLAIN SELECT * FROM test WHERE a = 1 AND b = 2;`
  • 结果 :会使用 idx_a_b 索引(key: idx_a_b)。
查询 2:WHERE b = 2 AND a = 1(条件顺序相反)
复制代码

sql

复制代码
`EXPLAIN SELECT * FROM test WHERE b = 2 AND a = 1;`
  • 结果
    • MySQL 5.7+ 和 8.0 :优化器会自动重写为 WHERE a = 1 AND b = 2,仍然使用 idx_a_b
    • 旧版本 MySQL:可能无法利用索引,导致全表扫描。

3. 关键结论

  1. 索引顺序是物理存储顺序,查询必须从最左列开始才能高效利用。
  2. MySQL 优化器会尝试重写条件 ,因此 WHERE b = ? AND a = ? 在大多数现代版本中仍能利用 (a, b) 索引。
  3. 但依赖优化器不可靠 ,建议显式写成 WHERE a = ? AND b = ? 以确保索引被使用。

4. 其他相关场景

(1) 只查询 b 列(WHERE b = ?

  • 无法利用 (a, b) 索引 ,因为缺少 a 的条件。
  • 解决方法:
    • 单独为 b 创建索引。
    • 使用覆盖索引(如 (b, a))。

(2) 范围查询 + 精确匹配

  • WHERE a = 1 AND b > 10:可以利用 (a, b) 索引(先定位 a = 1,再在范围内找 b > 10)。
  • WHERE a > 1 AND b = 10只能用到 a 的部分索引 ,因为 b 的条件在范围查询后无法高效过滤。

5. 最佳实践

  1. 遵循最左前缀原则:查询条件从索引的最左列开始。
  2. 显式书写条件顺序 :避免依赖优化器重写,直接写 WHERE a = ? AND b = ?
  3. 使用 EXPLAIN 验证:检查执行计划是否真的用了索引。
  4. 考虑索引覆盖 :如果只需查询 ab,确保索引包含所有需要的列(如 INDEX idx_a_b (a, b))。

总结

  • WHERE b = ? AND a = ? 在现代 MySQL 中通常能利用 (a, b) 索引(因优化器重写)。
  • 但最安全的方式是显式写成 WHERE a = ? AND b = ?
  • 如果查询不符合最左前缀(如仅 WHERE b = ?),则无法利用 (a, b) 索引

建议通过 EXPLAIN 实际验证查询计划!

相关推荐
jiayou646 小时前
KingbaseES 表级与列级加密完全指南
数据库·后端
GBASE1 天前
G术时刻 |GBase 8s数据库事务并发控制之封锁技术介绍(下)
数据库
xiezhr2 天前
逛GitHub发现了一款免费的带AI功能的数据库管理工具
数据库·ai编程·dba
唐青枫2 天前
MySQL JSON 实战详解:从存储、查询、更新到 JSON_TABLE 与索引
sql·mysql
吃糖的小孩2 天前
给 QQ AI 机器人设计“可控记忆”:会话摘要、手动长期记忆与角色卡边界
数据库
小满8782 天前
5.Mysql事务隔离级别与锁机制
mysql
笃行3503 天前
金仓数据库数据安全双防线:静态存储加密与传输加密实战
数据库
笃行3503 天前
金仓数据库物理备份实战:sys_rman 全流程演练与误覆盖抢救
数据库
笃行3503 天前
金仓数据库逻辑备份实战:从全库导出到 Schema 替换的完整闭环
数据库
元Y亨H3 天前
技术笔记:MySQL 字符集排序规则与大小写敏感性问题解决方案
mysql