Cartesian Join 和 BroadcastNestedLoop 在 Spark 中的区别

Difference Between Cartesian Join and BroadcastNestedLoop join in Spark

我浏览了几篇文章,但最终无法准确弄清楚它们之间的确切区别是什么。他们都以叉积的方式扫描每条记录的 tables。他们说在 BroadcastNestedLoop 中,较小的 table 被广播到所有工作节点。在笛卡尔连接的情况下,这种改组是如何发生的?能否请您解释一下 Spark 中的两种连接策略到底有什么不同。

嵌套循环连接

嵌套循环连接是SQL中最基本的连接算法(不仅在Spark中)。在pseudo-code中可以描述为:

O_SET     # outer query set
I_SET     # inner query set
PREDICATE # join predicate

foreach o_row in O_SET:
  foreach i_row in I_SET:
    if i_row matches PREDICATE:
      return (o_row, i_row)

广播嵌套循环加入

在Broadcast Nested Loop Join中,其中一个输入数据集被广播给所有的执行者。在此之后,non-broadcasted 输入数据集的每个分区都使用标准的嵌套循环连接过程连接到广播数据集,以生成输出连接数据。

因此广播嵌套循环连接不会产生“all-to-all”作为笛卡尔连接的连接。

笛卡尔连接

Cartesian Join专门用于在两个输入数据集之间执行交叉连接。由于交叉连接是两个数据帧的“all-to-all”记录的连接,因此数据集的整个分区被发送或复制到所有分区。

输出分区数总是等于输入数据集分区数的乘积。对于输出数据集中的每个输出分区,通过对映射到输出分区的两个输入分区的数据进行笛卡尔积来计算数据。