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 时要 遵循索引的顺序,才能发挥索引的最大性能!🚀

相关推荐
NineData25 分钟前
杭州 OpenClaw 开发者聚会来了!NineData 叶正盛将带来主题分享
数据库·人工智能
wang2455981992 小时前
【MySQL基础篇】概述及SQL指令:DDL及DML
sql·mysql·oracle
2401_898075122 小时前
Python在金融科技(FinTech)中的应用
jvm·数据库·python
IvorySQL3 小时前
PostgreSQL 技术日报 (3月14日)|AI 落地 PostgreSQL 拒绝 PPT 空谈
数据库·postgresql·开源
JavaGuide3 小时前
鹅厂面试:SELECT * 一定导致索引失效?常见索引失效场景有哪些?
java·数据库·后端·mysql·大厂面试
wmfglpz883 小时前
NumPy入门:高性能科学计算的基础
jvm·数据库·python
泯仲4 小时前
从零起步学习MySQL 第十二章:MySQL分页性能如何优化?
数据库·学习·mysql
IvorySQL4 小时前
直播预告|PostgreSQL 18.3 x IvorySQL 5.3:开启 AI 数据库新纪元
数据库·postgresql·开源
TDengine (老段)4 小时前
TDengine IDMP 组态面板 —— 创建组态
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据