在写left join的时候 是大表在左侧 还是小表在左侧(一)

news/2025/10/21 15:35:19/文章来源:https://www.cnblogs.com/jelly12345/p/19155555

好——这个问题既是面试高频点,也是写生产 SQL 时必须搞清楚的性能细节。下面把概念 + 引擎实现 + 左连接(LEFT JOIN)语义影响 + 实际优化建议与排查清单都讲清楚,你能直接在面试里条理化回答,也能在工程中落地排查与优化。

结论先说一句话

  • 性能上通常希望“驱动(build/probe)侧是小表”:无论是嵌套循环(Nested-Loop)还是哈希(Hash)连接,数据库都倾向于对小表做构建或做外层遍历以减少工作量。

  • 但对 LEFT JOIN(外连接)要小心:外连接的语义限制了优化器随意重排表顺序,因此如果你想让小表做“驱动”,需要注意写法或使用 hint/STR AIGHT_JOIN 强制。Database Administrators Stack Exchange+1


1) 先看:数据库常见的连接算法(会影响“谁做”)

  • 索引嵌套循环(Index Nested-Loop):外层逐行扫描,内层用索引按键快速查找。适合外层较小或内层有合适索引的场景。MySQL 传统上大量使用这种方式。Medium

  • 哈希连接(Hash Join):先对“较小的一方”构建哈希表(build),再扫描“较大的一方”并 probe 哈希表匹配。MySQL 从 8.0.18 起支持 hash join(主要用于等值内连接)。因此哈希连接更要求把小表作为 build side。MySQL开发者区+1

  • 排序合并(Sort-Merge Join):对两边排序后线性合并(MySQL 对此支持受限,具体实现/可用性与版本有关)。Medium

结论:不论哪种算法,把更小、选择性更高、或能建立索引的表放在“build/外层”通常更高效(少 I/O、少 probe/比较)。


2) LEFT JOIN 的语义与优化器重排问题(面试必问点)

  • LEFT JOIN a LEFT JOIN b 的语义:左表的每一行必须保留(即使右表无匹配,用 NULL 填充)。这语义限制了优化器能做的重排(不能随意把右表当做外层表来改变逻辑结果)。MySQL 优化器在重写/重排连接时要保证外连接的语义不被破坏,因此在某些情况下无法或不会把右表提前为驱动表MySQL开发者区+1

  • 实战结果:对 LEFT JOIN,想让小表“先被处理”需要注意

    • 如果你用的是内连接(INNER JOIN),优化器可自由重排,通常会选最优驱动顺序(常把小表做 build)。

    • LEFT JOIN 有语义约束,优化器可能必须先读取左表,然后为每行查右表(外层为左表),这在左表非常大时可能代价高(大量探针)。因此如果左表很大而你希望效率更高,需考虑改写或调整索引/提示。Stack Overflow+1


3) 实际建议(工程化可执行的规则)

下面按“你能马上应用”的清单写,便于面试与工程落地。

A. 优先保证索引(最重要)

  • 无论 join 顺序,右表(被查找表)的 join 列必须有合适索引,这样即便外层是大表,内层也能快速通过索引定位匹配,避免全表扫描。

B. 让“更小的表作为 build/驱动”——如何做到

  • 如果是 INNER JOIN:数据库会倾向于最优驱动顺序(小表做 build)。只需确保统计信息和索引正确。

  • 如果是 LEFT JOIN,但语义上你可以把逻辑改成等价的 INNER JOIN(例如把过滤条件提早到 ON/WHERE,使行必然匹配),那就改为 INNER JOIN。否则:

    • 重写查询:用子查询先把小表聚合/筛出(derived table/临时表),对其建立索引或物化,再 join 大表。

    • 用 STRAIGHT_JOIN 强制顺序(MySQL):SELECT /*+ STRAIGHT_JOIN */ ...STRAIGHT_JOIN 关键字,让写表顺序成为驱动顺序(小心语义与正确性)。

    • 利用 optimizer hints(MySQL 8.0+)JOIN_ORDER() 等 hint(视版本)来影响重排。

C. 对于 MySQL 8+:若能用 Hash Join,效果更好

  • 在 MySQL 8.0.18+ 若走 hash join,查询会先对小表构建 hash,然后扫描大表 probe;这符合“小表先做 build”的规则。检查 EXPLAIN 看是否采用 hash join。MySQL开发者区

D. 避免产生过多临时结果与排序

  • 如果 JOIN 前没有先筛选,会乘法级别扩大中间行数(导致 temp table / disk spill)。尽量把过滤(WHERE 条件)尽早下推或先在 derived table 中做聚合/筛选,减少中间集大小。

E. 监控与调整参数(MySQL 特有)

  • 若查询使用大量全表扫描,MySQL 可能使用 join_buffer(用于没有索引时的块嵌套)。可查看 join_buffer_size,但更优是补索引或改写查询。

  • 对 HASH JOIN,注意内存和 hash 表大小(由服务器自动控制,但需要关注内存使用)。use-the-index-luke.com


4) 排查步骤(在生产中你应该怎么做)

  1. 先用 EXPLAINEXPLAIN ANALYZE(MySQL 8)查看执行计划(观察 join type、possible_keys、rows、Extra 是否用 Using where/Using index/Using temporary)。

  2. 看 optimizer 是否选择 nested-loop、hash join 或全表扫描。若是 nested-loop 且外层是大表且内层没有索引 → 性能问题的常见原因。Medium

  3. 若 LEFT JOIN 导致外层大表全表扫描且结果慢,考虑:加索引 / 将小表先聚合成临时小表 / 改写成 EXISTS(有时 EXISTS 更高效)或使用 STRAIGHT_JOIN 强行改变执行顺序测试效果(注意语义)。Database Administrators Stack Exchange+1

  4. 做对比测试(改写前后在测试库跑 explain / timing),不要盲目在生产直接改写。


5) 常见面试问答要点(简短可背)

  • 问:LEFT JOIN 时哪个表放左边更好?
    答:语义上左边是要保留的表;性能上你通常希望 小表作为 build / 驱动(这样 probe 次数少)。但 LEFT JOIN 的语义可能禁止优化器把右表先做驱动,因此如果左表很大需要改写查询或使用 hint/临时表来让小表先被处理。务必保证被 probe 的表有索引,并用 EXPLAIN 验证执行计划。Database Administrators Stack Exchange+1

  • 问:MySQL 支持哈希连接吗?会影响 join 顺序吗?
    答:从 MySQL 8.0.18 开始支持 Hash Join(主要用于等值内连接),Hash Join 会把小表做 build并对大表 probe;因此在能走 hash join 时,使小表为 build side 性能更优。MySQL开发者区+1


6) 小结 — 实战优先级

  1. 先看执行计划(EXPLAIN) —— 确认 join 算法、是否有索引、rows 估算。

  2. 保证 join 列有索引(特别是被查表的列)。

  3. 尽量让小表做 build/驱动:对于 INNER JOIN 由优化器处理;对于 LEFT JOIN,若左表很大且性能差,考虑改写(子查询/derived)或 hint/STRAIGHT_JOIN。

  4. 考虑 Hash Join(MySQL 8.0.18+):当可用时对大表/小表组合很有利(小表作 build)。

  5. 用实际测量(EXPLAIN ANALYZE / timing)来验证每一步,别凭直觉改造查询。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/942336.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用POI-TL组件按模板导出word文档

使用POI-TL组件按模板导出word文档效果展示:以及更多的效果,可以访问官方文档示例 > https://deepoove.com/poi-tl/示例 依赖引入:<dependencies><!-- poi-tl 核心依赖 --><dependency><gr…

【IEEE出版】2025年智能控制与计算科学国际学术会议 (ICICCS 2025)

2025年智能控制与计算科学国际学术会议 (ICICCS 2025)将于2025年11月14-16日在中国南通举办。ICICCS 2025将汇聚来自全球的学者、研究人员和行业专家,共同探讨智能控制与人工智能领域的最新进展与创新应用。本次会议…

2025 年地铺石厂家最新推荐榜:涵盖生态/仿石/陶瓷等品类,揭秘行业口碑优质企业18厚/火烧/庭院/陶瓷地铺石厂家推荐

引言 当前地铺石市场需求随城市化建设持续增长,但行业乱象却让采购者举步维艰。一方面,产品质量两极分化严重,部分厂商用劣质原料生产的地铺石,抗压、防滑性能不达标,短期内就出现破损、开裂问题,给工程安全与美…

2025-10-20-随感

一晃时间来到了2025年,真真切切成了一个老程序员,还是多记录吧,证明自己还是那么努力过 一:maven编译时强制拉取快照包 需要加上-U 二:tomcat服务下lib包的地址 /web/servers/tomcat/webapps/ROOT/WEB-INF/lib

2025电源适配器厂家推荐,华威仕电子科技专业制造实力企业

2025电源适配器厂家推荐,华威仕电子科技专业制造实力企业 当前电源适配器领域技术挑战与行业现状 随着电子设备市场的持续扩张,电源适配器作为关键配套产品,面临着前所未有的技术挑战。据行业数据显示,全球电源适配…

Jupyter Notebook下载安装启用教程(附安装包,图文并茂)

Jupyter Notebook下载安装启用教程(附安装包,图文并茂)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consola…

语音文字图片工具箱微信小程序:多功能工具与高效变现解决方案

一、概述总结 语音文字图片工具箱微信小程序,是基于微擎系统交付的多功能工具类应用,支持无限多开,兼具实用工具属性与商业变现能力。其核心优势在于整合语音、文字、图片相关高频功能,同时提供流量主广告、微信支…

酷鸭写真分销版小程序系统:AI 驱动的写真变现工具

一、概述总结 酷鸭写真分销版是一款集成微信与抖音小程序的系统,以 AI 技术为核心,提供美颜写真、酷码生成、艺术照片三大核心功能。系统无需用户编写复杂咒语,仅需上传图片即可生成内容,同时支持分销模式,兼顾内…

天天享赚微信小程序:流量主与猜成语结合的变现工具详解

1. 概述总结 “天天享赚” 是一款基于微擎系统交付的微信小程序,核心定位为 “游戏互动 + 流量主变现”。它以 “看图猜成语” 为核心玩法,通过植入普通广告与激励广告实现收益,同时支持功能更新与多版本迭代。 2. …

微信小程序域名查询系统详细介绍

一、概述总结 微信小程序域名查询系统是一款基于微擎系统的实用工具类应用,核心功能是帮助用户在线查询小程序名称的注册状态,目前在微擎应用商城以 “服务套餐” 形式售卖,主打为商家及销售团队提升服务效率。 该系…

TLS1.2 和 TLS1.3的简要区别

TLS1.2 和 TLS1.3的简要区别_tls1.2和tls1.3-CSDN博客

[极客大挑战 2019]Havefun 1 代码审计

题目界面查看网页源代码发现注释代码,使用get参数?cat=dog得到flag

2025粘度计厂家权威推荐:华宇忠宜在线旋转振动多场景精准测量

2025粘度计厂家权威推荐:华宇忠宜在线旋转振动多场景精准测量 在工业生产过程中,粘度测量作为关键工艺参数监测环节,其准确性直接影响产品质量与生产效率。随着工业自动化水平的不断提升,传统离线粘度测量方式已难…

2025 年合肥养老院最新推荐排行榜权威发布:甄选优质机构,深度解析医养结合优势与选择指南合肥智慧/医养结合/社区/瑶海区养老院推荐

引言 当前合肥老龄化进程加快,家庭养老压力递增,养老院成为众多家庭的重要选择。但市场上养老院质量参差不齐,部分机构存在医疗配套不足、服务不规范、设施陈旧等问题,加之信息不对称,家属难辨机构优劣,挑选合适…

程序流程结构

程序流程结构 C/C++支持最基本的三种程序运行结构:顺序结构,选择结构,循环结构 顺序结构:程序按顺序执行,不发生跳转 选择结构:依据条件是否满足,有选择的执行相应功能 循环结构:依据条件是否满足,循环多次执…

oracle查询某一天的数据,即日期条件使用

1.推荐使用范围查询,即 SELECT * FROM your_table WHERE date_column >= TO_DATE(2023-01-31, YYYY-MM-DD) AND date_column < TO_DATE(2023-01-31, YYYY-MM-DD) + 1; 这种方法对于任何日期(包括月末、闰年等…

Redis 哨兵模式搭建教程(基于 Docker,附完整配置与避坑指南)

引言 Redis 哨兵模式(Sentinel)是实现 Redis 高可用的核心方案,能够自动监控主从节点状态,并在主节点故障时完成自动故障转移。本文基于 Docker 环境,详细讲解如何在两台服务器(IP 分别为172.16.126.21和172.16.…

程序内存模型

内存的分区模型 C++程序在执行时,将内存大方向划分为4个区域 代码区:存放函数体的二进制代码,由操作系统进行管理的 全局区:存放全局变量和静态变量以及常量 栈区:由编译器自动分配释放,存放函数的参数值,局部变…

如何从0到1制作一个免费的二维可视化项大屏

在数据驱动决策的时代,二维可视化大屏成为直观呈现数据价值的重要载体。山海鲸可视化作为零代码工具,凭借丰富的组件库与灵活的操作逻辑,让普通用户也能轻松打造专业级大屏。本文将以互联网安全监测大屏为例拆解从 …

2025 年集成电路封装厂家最新推荐榜:甄选技术领先实力厂家,涵盖制造检测测试领域权威名录

引言 2025 年半导体产业加速向先进封装迭代,封装环节作为芯片性能释放的核心载体,直接决定下游产品竞争力。当前市场呈现 “新旧品牌并存、技术层次分化” 格局,传统企业坚守成熟工艺,近五年崛起的新势力则在 Chip…