当前位置: 首页 > news >正文

LEFT JOIN 中 ON 与 WHERE 过滤的差异

在 MySQL 数据库开发中,LEFT JOIN(左外连接)是一个最常被误用的语法。许多开发者往往习惯性地将所有过滤条件一股脑地往ON后面塞,或者为了排版好看将条件全部扔到WREHRE里面。

这种模糊的逻辑在普通内连接(INNER JOIN)中确实没有区别,但在LEFT JOIN中,多条件写在 ON 还是 WHERE,会导致完全不同的执行结果与查询性能


1. 核心结论:一句话总结

  • 写在ON里面:代表连接条件。不论右表是否满足此条件,左(驱动)表的数据绝对不会丢。若右表不满足,右表字段直接补NULL
  • 写在WHERE里面:代表过滤条件。它是对关联后的整个结果集进行大筛查。一旦右表字段因不满足而被补了NULL,它就会在WHERE过滤中被彻底抹去

2. 真实案例单步拆解

为了还原现场,我们准备两张最简单的基础表:

表 a(商品表)

f1 (商品ID)name (商品名)
1苹果
2香蕉

表 b(价格表)

f1 (商品ID)f2 (促销价格)
130
250

场景一:多条件写在ON之中(促销条件关联)

SELECT*FROMaLEFTJOINbON(a.f1=b.f1ANDb.f2=30);
MySQL 底层单步执行逻辑:

由于是LEFT JOIN,表a被指定为驱动表。执行器会拿着表a的数据,一行行去匹配表b,匹配的硬性考核指标是:a.f1 = b.f1并且b.f2 = 30

  1. **处理“苹果”行(1, '苹果')**:拿着f1=1去表b找,找到了满足b.f1=1的行,紧接着评估第二个条件b.f2=30。此时30=30匹配成功。
  • 本步结果→\rightarrow(1, '苹果', 1, 30)
  1. **处理“香蕉”行(2, '香蕉')**:拿着f1=2去表b找,找到了b.f1=2的行,但它的b.f2是 50,不满足b.f2=30的要求。
  • 关键机制:因为是LEFT JOIN,左表数据不能丢。既然表b没有行能同时满足这两个条件,那就强行输出“香蕉”,右表全部填NULL
  • 本步结果→\rightarrow(2, '香蕉', NULL, NULL)
最终场景一输出结果:
a.f1a.nameb.f1b.f2
1苹果130
2香蕉NULLNULL

语义总结:“我只想和表 b 中价格是 30 的促销项连。如果它不是 30,我就不跟它连,但我自己(表 a)依然要保留,右边展示为 NULL 即可。”


场景二:条件挪到WHERE之中(连接后过滤)

SELECT*FROMaLEFTJOINbON(a.f1=b.f1)WHEREb.f2=30;
MySQL 底层单步执行逻辑:
  1. 第一阶段(连接):首先只看ON (a.f1 = b.f1),此时“苹果”和“香蕉”都能正常连上表b。生成一个中间临时结果集:
  • 记录一:(1, '苹果', 1, 30)
  • 记录二:(2, '香蕉', 2, 50)
  1. 第二阶段(大过滤):连接完全结束后,WHERE b.f2 = 30开始收网。执行器检查上面两条记录,发现记录二的b.f2是 50,不符合WHERE条件,当场予以剔除(消失)
最终场景二输出结果:
a.f1a.nameb.f1b.f2
1苹果130
⚠️ 惊人的幕后优化:驱动表被调换了!

在场景二中,既然WHERE条件强制限定了b.f2 = 30,这意味着表b中所有不匹配或者补NULL的行统统都是无效的。
MySQL 优化器敏锐地发现了这一点,会在后台默默将这个LEFT JOIN直接改写为内连接(INNER JOIN)。改写后,由于表b带有b.f2 = 30的强过滤条件,数据集更小,右表b反而会反客为主,变成真正的驱动表


3. 避坑指南:如何防范?

为了避免線上环境列表无故少数据,或者多出了全是NULL的垃圾数据,我们在写外连接时需要遵守以下原则:

  1. 明确逻辑目的
  • 如果你要找的是“不满足某些条件的残缺对照”(例如:查出所有没有参加 30 元促销的商品),必须把条件写在ON里,并配合右表主键IS NULL过滤。
  • 如果你仅仅是想对右表进行结果筛选,请直接写JOIN,不要写LEFT JOIN
  1. 利用EXPLAIN脑补流程
    如果你写了LEFT JOIN却在Extra字段里看到了Using where,且第一行的表(驱动表)变成了右表,说明你的WHERE条件已经打破了LEFT JOIN的语义,被优化器降级改写了。

在处理多表关联的业务(如复杂报表、用户主页信息流)时,多花半分钟确认过滤条件在ON还是WHERE,能为你省下大量的线上 Debug 时间。

http://www.jsqmd.com/news/862820/

相关文章:

  • 2026年必看:六款热门AI编程工具横评,Trae与Cursor怎么选
  • 2026最新诚信优选 福州市长乐区黄金回收白银回收铂金回收彩金回收门店TOP5排行榜+联系方式推荐_转自TXT - 盛世金银回收
  • 2026最新诚信优选 桂林市七星区黄金回收白银回收铂金回收彩金回收门店TOP5排行榜+联系方式推荐_转自TXT - 盛世金银回收
  • 2026年广州开发小程序哪家好?实测推荐!
  • 《从 0 实现 SGLang》第 1 篇 · LLM 推理引擎到底在做什么
  • 移动端 Agent:端上推理与云端协作设计
  • 医疗设备摄影
  • 从低空协议劫持实战看 MAVLink 二进制审计在飞控发布环节的必要性
  • 天勤策略钉钉告警:交易信号与异常通知怎么分流
  • 2026最新诚信优选 桂林市象山区黄金回收白银回收铂金回收彩金回收门店TOP5排行榜+联系方式推荐_转自TXT - 盛世金银回收
  • 批量将目录下的栅格数据重采样至不同分辨率
  • 2026年最佳手机阅读器推荐:付费也值得的精品选择
  • 解密Palantir系列一:1. 决策的三元闭环
  • 专业做绝对值编码器的服务商
  • C 语言通讯录(终版)|新手踩坑全总结 + 最终可运行代码博客简介
  • MySql存储引擎与索引
  • AI API 实践三:为什么要关注 Token,而不只是请求次数?
  • 淮南家长必看:淮南哪里学少儿编程靠谱?原来这样选才不踩坑。
  • 油雾净化设备哪家技术更专业
  • VMware虚拟机安装及配置
  • AI API 中转站完全指南:从 Claude、GPT 到“满血”“翻车”,一次搞懂整个 AI API 圈子
  • 2026年想做美缝施工?专业靠谱的美缝施工究竟哪家好?
  • 阿盖洛印相×真实银盐底片对比实测:27组DxO基准图像分析证明——MJ v6.2已逼近1930年代Kodak Azo纸动态范围(附测试集下载)
  • 一幅精细绝伦的[城市或地点]微缩模型
  • 从CDP“3A”到千亿美元目标:联想集团的创新路径与AI原生转型
  • python中二维数组初始化陷阱
  • (QBuffer配合 QDataStream)二进制序列化
  • 影刀RPA 从0到1:自动化系统架构收敛与工程化演进总结
  • 面向诊断场景的云产品知识库设计方案
  • 今日实测有效的淘宝闪购外卖/京东外卖/美团外卖红包天天领取口令怎么领今天可用的外卖红包神券?