在Spark DataFrame中进行高效联接

时间:2018-10-16 17:23:36

标签: scala apache-spark join apache-spark-sql distributed-computing

我试图在同一DataFrame上顺序加入DataFrame(dfA)。 假设dfA的列为id_xid_y,而dfB的列为id和其他一些列。

我想执行以下操作:

dfA.join(dfB, dfA("id_x") === dfB("id")).join(dfB, dfA("id_y") === dfB("id"))

我可以做些重新分区或预处理来加快速度吗?

2 个答案:

答案 0 :(得分:1)

您使用的是哪个版本的spark? 调整Spark是一门艺术,本身就是一个巨大的话题。盲目增加分区数并不能总是有帮助的。我建议看一下以下地方以寻找线索:

  1. 仔细查看Spark UI并分析您的DAG。瓶颈在哪里?它在等待CPU,内存,磁盘IO吗?洗牌太多?
  2. 您的数据是否歪斜?几乎没有长时间运行的任务,而大多数任务很快完成了?
  3. 您使用了哪种转换?请尽可能粘贴您的代码摘录。
  4. 装箱是Spark中的一项新功能,广泛预期可以帮助加入。但是,对DAG进行调查始终是最好的线索。
  5. 还基于您的代码,在什么情况下您想使用dfA(“ id_x”)和dfA(“ id_y”)与dfB(“ id”)联接?您可能可以在连接条件下尝试一些以下操作,而不是使用OR

    val joinCondition = when($“ dfA.id_y” .isNull,$“ dfA.id_y” === $$“ dfB.id”) .otherwise($“ dfA.id_x” === $$“ dfB.id”)

    val dfJoined = dfA.join(dfB,joinCondition)

请让我知道您的发现。

答案 1 :(得分:0)

您可以1次加入:

dfA.join(dfB, dfA("id_x") === dfB("id") or dfA("id_y") === dfB("id"))

您也可以使用spark.sql.shuffle.partitions或尝试广播一个数据帧。在联接之前进行重新分区将无济于事,但使用存储桶表可能会有所帮助,因为这可以避免在联接期间进行重新分配,请参见例如。 https://issues.apache.org/jira/browse/SPARK-12394