我有两个数据框。 df1
有100000行,而df2
有10000行。
我想创建一个df3
,这是两者的交叉连接:
val df3 = df1.crossJoin(df2)
这将产生10亿行。试图在本地运行它,但似乎需要永远。您认为可以在本地完成吗?
如果不是,哪种配置可以优化在云上运行该配置的时间?
答案 0 :(得分:1)
首先,我同意– Mpizos Dimitris,您应该尝试提供所有可能的细节,以获得最佳的解决方案。
但是下面是一种可能但可能不是有效的方法。
1。对小型DataFrame df2进行缓存并重新分区。确保通过重新分区将数据均匀地分布在所有工作服务器上,以便您可以使用尽可能多的任务。假设您的集群有20个工作人员,每个工作人员有4个核心。因此,您需要4 x 10 = 80个分区。
df2.repartition(80).cache()
2。在DF2上执行操作,以便在作业开始之前进行缓存。检查SparkUI的“存储”选项卡,确保产品DF缓存已分发到所有节点上。
df2.show(10)
3。暂时禁用广播加入。广播联接不适用于笛卡尔产品,因为工人获得了太多的广播数据,他们陷入了无限的垃圾收集循环中,并且永远无法完成。请记住,在查询结束时将其重新打开。您可以将以下配置设置为禁用BC连接。
spark.sql.autoBroadcastJoinThreshold = 0
4。在不使用联接条件的情况下将DF1与DF2联接。
val crossJoined = df1.join(df2)
5。在执行以确认您具有笛卡尔乘积运算之前,在DataFrame上运行一个解释计划。
crossJoined.explain