为什么在SQL中CROSS JOIN有时比LEFT JOIN执行计划更优

浅伟小哥_3920

浅伟小哥_3920

2026-09-16

961人浏览

原创

cross join在无条件关联时语义最干净、优化器最易推理,可跳过null判断等开销,支持更优执行策略如广播、哈希连接或并行处理;而left join因需保留左表及填充null,执行计划更复杂、性能通常更低。

为什么在sql中cross join有时比left join执行计划更优

CROSS JOIN在无条件关联时可能触发更优执行策略

当两个表之间本就不存在逻辑上的连接条件(比如纯枚举组合、配置生成、测试数据填充),CROSS JOIN反而是语义最干净、优化器最易推理的写法。此时数据库无需处理“保留左表 + 尝试匹配右表 + 填充NULL”这一整套外连接逻辑,可直接选择哈希构建+广播(broadcast)或批处理循环,跳过外连接特有的行保留标记、NULL传播判断等开销。

常见错误现象:有人把 LEFT JOIN 当“万能兜底写法”,哪怕业务上根本不需要保留左表全量,也硬写成 LEFT JOIN ... ON 1=1 或漏写 ON 条件——这会让优化器误判语义,强制走嵌套循环外连接,还可能引发临时表膨胀。

  • 真正需要全量保留左表时,才用 LEFT JOIN
  • CROSS JOIN 没有 ON 子句,优化器明确知道这是笛卡尔积,不会尝试“规避NULL”或“保序”
  • 某些版本 MySQL(如 8.0.25+)对无条件 CROSS JOIN 会自动启用 block_nested_loop 优化,而 LEFT JOIN ... ON 1=1 仍被当作普通外连接处理

LEFT JOIN的NULL填充机制拖慢执行计划

LEFT JOIN 的执行计划中必然包含“Null-aware join”步骤:对每条左表记录,不仅要查右表是否有匹配,还要确认是否要补 NULL 行;若右表有索引但未命中,引擎仍需执行一次“空结果判定”,这部分开销在高基数左表下会被放大。

而 CROSS JOIN 完全跳过这个判定——它默认每条左表记录都要配齐所有右表记录,不涉及“是否存在”的分支逻辑,CPU 分支预测更友好,向量化执行也更稳定。

  • 看 EXPLAIN 输出时,留意 Extra 列是否出现 Using where; Using join buffer(LEFT JOIN 常见),而 CROSS JOIN 多为 Using join buffer(少一层过滤)
  • 若右表是小维度表(如 status_codes 仅 10 行),CROSS JOIN 很可能被优化器自动转为 const 或 system 访问类型
  • MySQL 5.7 中,LEFT JOIN ... ON 1=1 仍会走 BNL(Block Nested Loop),但 CROSS JOIN 在满足内存阈值时可走更轻量的 hash join

驱动表与连接顺序对CROSS JOIN更友好

CROSS JOIN 不受连接方向语义约束,优化器可自由选择驱动表;而 LEFT JOIN 要求左表必须全部输出,通常锁定左表为驱动表——哪怕它是大表,也无法重排。

例如:SELECT * FROM large_orders CROSS JOIN small_status,优化器大概率选 small_status 为驱动表,广播其全量到每个 large_orders 分区;但写成 LEFT JOIN 就只能以 large_orders 为驱动,导致重复扫描次数暴增。

  • 用 EXPLAIN FORMAT=TREE 查看实际驱动顺序,CROSS JOIN 的树结构通常比 LEFT JOIN 更扁平
  • SQL Server 中,CROSS JOIN 可能触发 Batch Hash Join,而同场景下 LEFT JOIN 因需保留 NULL 行,被迫退化为 Row Mode Hash Join,吞吐下降明显
  • PostgreSQL 14+ 对 CROSS JOIN 支持 parallel hash join,但对 LEFT JOIN 的并行支持仍有限制(尤其含聚合时)

真正容易被忽略的是:JOIN 类型不是性能开关,而是语义契约。当你发现 CROSS JOIN 比 LEFT JOIN 快,首先要确认业务是否真的需要“保留左表全量”——如果答案是否定的,那慢的从来不是 LEFT JOIN,而是你写错了语义。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

4283

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

911

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1109

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

6201

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

3043

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

6180

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

8341

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1130

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

992

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.7万人学习