Scala 为高效的左连接对大型数据帧进行分区?

Scala 为高效的左连接对大型数据帧进行分区?,scala,apache-spark,dataframe,left-join,Scala,Apache Spark,Dataframe,Left Join,我有两个具有相同结构的大型数据帧,数据量大致相同,我将它们连接起来,以确定一个DF中是否有任何行丢失,而另一个DF中没有。数据帧足够大(高达8000万行,或~40Gb),使广播连接成为不可选项。缺少行的数量通常很小,在最坏的情况下高达10K。联接在2-4列(两侧相同)上的表达式上,形式为concat(coalesce(colA),“,”,“|“,”,coalesce(colB),“,”,“|”,coalesce(colC,”)),因为某些键列可以为NULL 我们正在考虑使用分区(在连接之前或之后

我有两个具有相同结构的大型数据帧,数据量大致相同,我将它们连接起来,以确定一个DF中是否有任何行丢失,而另一个DF中没有。数据帧足够大(高达8000万行,或~40Gb),使广播连接成为不可选项。缺少行的数量通常很小,在最坏的情况下高达10K。联接在2-4列(两侧相同)上的表达式上,形式为
concat(coalesce(colA),“,”,“|“,”,coalesce(colB),“,”,“|”,coalesce(colC,”))
,因为某些键列可以为NULL


我们正在考虑使用分区(在连接之前或之后),因为连接导致的混乱似乎会导致生产环境中的低性能。对于有效的左连接,建议使用什么方法对数据帧进行分区?

首先,如果在不更改至少一个数据帧的情况下多次执行
连接操作,分区可以提高
连接操作的性能

已经提供了类似的答案-在一次性
join
之前使用分区只会导致在不同的位置进行洗牌

join
之后使用分区将不会产生任何积极影响


在第61页的书中还解释了对
join
操作主题的分区效果。

对join使用多个子句(而不是将所有内容串联起来)和基于列的按该顺序分区可能会提高性能。此外,您是否考虑过使用Bloom过滤器或类似的东西?连接类型是否有区别?如果我以完全相同的条件连接两个数据集两次,但其中一个是左连接,另一个是右连接,那么预分区是否会提高性能,或者这些连接是否被认为是“不同的”连接?这与连接的类型无关。这是关于价值观的。考虑:
df.join(df2,“A”)
。要执行此连接,spark将把列中具有相同值的行移动到同一节点-这是洗牌。预分区也会这样做,但在连接操作之前。例如,如果在上述连接之后,你会做一些类似的事情:<代码> DF.Join(DF3,A)——我的意思是加入同一列——然后你可以考虑预分区——因为DF只会被拖动一次。否则,如果您有一组不同的列用于连接,那么预分区将没有帮助。