【问题标题】:Partitioning large dataframes for an efficient left join?对大型数据框进行分区以实现高效的左连接?
【发布时间】:2018-07-31 08:19:14
【问题描述】:

我有两个结构相同且数据量大致相同的大型数据框,我将它们左连接以确定一个 DF 中是否缺少任何行,而另一个则没有。数据帧足够大(最多 8000 万行,或 ~40Gb),使得广播连接不是一个选项。丢失的行数通常很少,最坏的情况下最多为 10K。连接是基于 2-4 列(两边相同)的表达式,格式为 concat(coalesce(colA, ""), "|", coalesce(colB, ""), "|", coalesce(colC, "")),因为某些键列可以为 NULL。

我们正在考虑使用分区(在联接之前或之后),因为联接引起的 shuffle 似乎会在我们的生产环境中导致性能下降。对数据帧进行分区以实现高效左连接的推荐方法是什么?

【问题讨论】:

  • 使用多个子句进行连接(而不是连接所有内容)并按该顺序基于列进行分区可能会给您带来良好的性能提升。
  • 另外,您是否考虑过使用布隆过滤器或类似的东西?

标签: scala apache-spark dataframe left-join


【解决方案1】:

首先,如果join 操作将被执行多次而不改变至少一个DataFrame,则分区可以提高join 操作的性能

here 已经提供了类似的答案 - 在一次性 join 之前使用分区只会导致在不同的地方随机播放。

join 之后使用分区不会有任何积极影响。

join 操作主题的分区效果在第 61 页的this 书籍中进行了说明。

【讨论】:

  • 连接类型有区别吗?如果我两次以完全相同的条件连接两个数据集,但一个是左连接,另一个是右连接 - 预分区会带来任何性能改进,还是这些被视为“不同”连接?
  • 这与连接类型无关。这是关于价值观。考虑:df.join(df2, "A")。要执行此连接,spark 会将 A 列中具有相同值的行移动到同一节点 - 这是洗牌。预分区将执行相同的操作,但在连接操作之前。例如,如果在上述加入之后,您将执行以下操作:df.join(df3, "A") - 我的意思是按同一列加入 - 那么您可以考虑预分区 - 因为 df 只会被洗牌一次。否则,如果您有不同的连接列集 - 预分区将无济于事。
猜你喜欢
  • 2010-10-14
  • 1970-01-01
  • 2018-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多