2-002:MySQL 索引的最左前缀匹配原则是什么?

MySQL 索引的最左前缀匹配原则

最左前缀匹配原则(Leftmost Prefix Matching) 是指:

查询使用了复合索引(联合索引) 时,MySQL 会优先匹配索引的 最左列 ,然后逐步向右匹配,直到遇到无法匹配的列,此时索引匹配停止,不会继续使用后续的列索引。


1. 复合索引示例

假设有一个 user 表,创建了如下 复合索引(联合索引):

sql 复制代码
CREATE INDEX idx_user ON user (name, age, city);

索引顺序

  • 第一列:name
  • 第二列:age
  • 第三列:city

此时,该索引可以加速如下查询:

可以使用索引的查询

sql 复制代码
SELECT * FROM user WHERE name = 'Tom';   -- 只用到了第一列 ✅
SELECT * FROM user WHERE name = 'Tom' AND age = 25;  -- 使用了前两列 ✅
SELECT * FROM user WHERE name = 'Tom' AND age = 25 AND city = 'Beijing';  -- 使用了全部索引列 ✅
SELECT * FROM user WHERE name LIKE 'T%';  -- 模糊匹配最左列 ✅
  • 以上 SQL 都符合 最左前缀匹配原则 ,因此 MySQL 会使用索引

不能使用索引的查询

sql 复制代码
SELECT * FROM user WHERE age = 25;  -- 跳过了第一列 ❌
SELECT * FROM user WHERE city = 'Beijing';  -- 跳过了第一、第二列 ❌
SELECT * FROM user WHERE age = 25 AND city = 'Beijing';  -- 跳过了第一列 ❌
SELECT * FROM user WHERE name LIKE '%T';  -- 以 % 开头 ❌

索引失效的情况

  1. 查询条件不包含索引的最左列 (如 age=25)。
  2. 跳过索引列 (如 age=25 AND city='Beijing',因为 name 没有出现,索引无法使用)。
  3. 最左列使用 % 开头的模糊查询 (如 name LIKE '%T',导致索引失效)。
  4. 在索引列上进行计算、函数操作 (如 WHERE LEFT(name, 2) = 'To',因为 LEFT() 破坏了索引匹配)。

2. 最左前缀索引的匹配规则

假设索引是 (A, B, C, D),查询时:

  • 能匹配 A → 可以使用索引
  • 能匹配 A, B → 可以使用索引
  • 能匹配 A, B, C → 可以使用索引
  • 跳过 A,直接匹配 B 或 C → 索引失效
  • 在 A 上使用函数、计算等操作 → 索引失效

3. 最左前缀匹配优化建议

  1. 尽量遵循索引的列顺序,避免跳过列。

  2. 尽量使用 = 或 IN 进行查询,避免索引失效。

  3. 不要对索引列进行计算或函数操作,否则 MySQL 无法利用索引。

  4. 如果范围查询 (>, <) 出现在某列,则索引匹配会终止,即:部分失效。如:

sql 复制代码
SELECT * FROM user WHERE name = 'Tom' AND age > 25 AND city = 'Beijing';

这里索引只能用到 name, age,但 city 不会被索引,因为 age > 25,使得 city失效。

解析:索引匹配顺序

  • name = 'Tom'索引匹配
  • age > 25索引匹配 ✅(但是因为是范围查询,后续索引匹配终止!
  • city = 'Beijing'索引失效 ❌(不会使用索引

🔴 为什么 city 列的索引失效?

  • MySQL 索引是按照 (name, age, city) 的顺序建立的,索引匹配是按顺序进行的
  • 一旦遇到范围查询(>, <, BETWEEN) ,MySQL 不会继续使用索引后面的列
  • age > 25 是一个范围查询,因此 索引匹配到 age 这里就停止了city 不能再用索引。

4. 总结

  • 最左列必须出现在查询条件中,否则索引失效!
  • 范围查询 (>, <, BETWEEN) 之后的索引列不再生效!
  • 索引匹配是按照最左列依次匹配的,中间不能跳过!

📌 牢记 :写 SQL 时要 遵循索引的顺序,才能发挥索引的最大性能!🚀

相关推荐
小小测试开发2 分钟前
SQL常用语法全解析:从入门到进阶的实战指南
数据库·sql
暗之星瞳4 分钟前
mysql练习
数据库·mysql
月上林梢6 分钟前
QT圆形加载进度条
数据库·c++·qt·进度条
3824278277 分钟前
汇编:条件汇编、
前端·汇编·数据库
Java水解15 分钟前
MySQL必备基础
后端·mysql
_李小白44 分钟前
【Android FrameWork】第三十三天:Camera视频流写入SurfaceView的机制
android
蜘蛛小助理1 小时前
研发团队效率神器:手把手教你用蜘蛛表格构建自动化任务管理中枢
数据库·自动化·任务管理·多维表格·蜘蛛表格
csj501 小时前
安卓基础之《(4)—Activity组件(2)》
android
计算机毕设VX:Fegn08951 小时前
计算机毕业设计|基于springboot + vue酒店管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
Hui Baby1 小时前
全局事务入口感知子事务方法-TCC
java·开发语言·数据库