MySQL——最左前缀法则

最左前缀法则是 MySQL 联合索引中最核心的生效规则。

简单来说:如果你建立了一个包含多个列的索引,就像是在通讯录里先按"姓"排、再按"名"排一样,查询时必须从索引的最左列开始,且不能跳过中间的列。

一、 核心逻辑:像"找名字"一样思考

假设创建了一个联合索引:INDEX(col1, col2, col3)

在底层的 B+ 树中,数据的排序逻辑是:

先根据 col1 排序。

col1 相同的情况下,再根据 col2 排序。

col2 相同的情况下,再根据col3排序。

二、 三种典型的应用场景

为了方便理解,我们假设索引是 (name, age, position)

  1. 全值匹配(完全生效)
    如果你在 WHERE 子句里用到了所有索引列,顺序无所谓(MySQL 优化器会自动调整顺序),索引完全生效。

WHERE name='张三' AND age=20 AND position='Dev'

  1. 部分匹配(部分生效)
    必须从最左边开始,连续匹配。

WHERE name='张三' ✅(用到了 name 索引)

WHERE name='张三' AND age=20 ✅(用到了 nameage 索引)

  1. 违反规则(失效)
    中间断档:WHERE name='张三' AND position='Dev'

结果:只有 name 用到了索引。因为跳过了 ageposition 在索引树里是无序的,无法直接定位。

非最左开头:WHERE age=20 AND position='Dev'

结果:完全失效。因为没有 name,数据库根本不知道从 B+ 树的哪一个分支开始找,只能全表扫描。

三、 两个致命的"断点"

除了跳过列,还有两种情况会导致最左前缀法则的后续部分失效:

  1. 范围查询(后面失效)
    在联合索引中,如果中间某个列使用了范围查询(>、<、BETWEENLIKE 'Zhang%'),那么该列之后的索引列将失效。

WHERE name='张三' AND age > 20 AND position='Dev'

效果:name 有效,age 有效,但 position 失效。

  1. 模糊查询(前缀通配符)
    WHERE name LIKE '张%' ✅(生效)

WHERE name LIKE '%张' ❌(失效,因为开头不确定,破坏了最左原则)

四、 为什么会有这个法则?

这是由 B+ 树的排序特性决定的。

在多列索引的 B+ 树中,只有左边的列相等时,右边的列才有序。

如果你直接找 age=20 的人,在整个 B+ 树里,age=20 的记录可能散落在"张三"的分支里,也可能在"李四"的分支里。

数据库无法通过一次 B+ 树的搜索直接抓取所有 age=20 的人,只能挨个分支去找,这和全表扫描没区别。

总结口诀

带头大哥不能死,中间兄弟不能断,范围之后全完蛋。

相关推荐
wjhx2 小时前
QT中对蓝牙权限的申请,整理一下
java·数据库·qt
冰暮流星2 小时前
javascript之二重循环练习
开发语言·javascript·数据库
万岳科技系统开发3 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法
冉冰学姐3 小时前
SSM智慧社区管理系统jby69(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·管理系统·智慧社区·ssm 框架
杨超越luckly3 小时前
HTML应用指南:利用GET请求获取中国500强企业名单,揭秘企业增长、分化与转型的新常态
前端·数据库·html·可视化·中国500强
斯普信专业组3 小时前
构建基于MCP的MySQL智能运维平台:从开源服务端到交互式AI助手
运维·mysql·开源·mcp
Elastic 中国社区官方博客3 小时前
Elasticsearch:Workflows 介绍 - 9.3
大数据·数据库·人工智能·elasticsearch·ai·全文检索
仍然.3 小时前
MYSQL--- 聚合查询,分组查询和联合查询
数据库
一 乐3 小时前
校园二手交易|基于springboot + vue校园二手交易系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端
啦啦啦_99993 小时前
Redis-0-业务逻辑
数据库·redis·缓存