避免广播嵌套循环连接

r.s*_*r.s 0 join apache-spark

当我使用左连接连接两个数据帧时,如下所示:

df1.join(broadcast(df2), $"id" === $"id1" || $"id2" === $"id3", "left")

如果没有$"id2" === $"id3",它执行得非常快,但是当这两个条件都存在时,它会BroadcastNestedLoopJoin变得非常非常慢。

我有什么想法可以改进这个吗?

小智 6

BroadcastNestedLoopJoin 意味着嵌套的 for 循环来连接数据帧。它总是会降低性能。

您可以尝试以下解决方案:

val resultPart1 = df1.join(broadcast(df2), $"id" === $"id1", "left")
val resultPart2 = df1.join(broadcast(df2),  $"id2" === $"id3", "left")

val resultDF = resultPart1.unionByName(resultPart2)
Run Code Online (Sandbox Code Playgroud)

联合导致执行器之间的数据零洗牌。因此产生更快的结果

  • resultPart1 和 resultPart2 中的记录不匹配怎么办?您最终会得到不需要的记录。 (2认同)