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

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,而是你写错了语义。

















