快速Spark替代WHERE column IN other_column的方法

问题描述 投票:2回答:1

我正在寻找一个快速的PySpark替代方案,以取代

SELECT foo FROM bar
WHERE foo IN (SELECT baz FROM bar)

事先收集到Python列表中是绝对不行的,因为处理的数据框相当大,而且相对于我想出的另一个方案来说,收集需要花费大量的时间。所以我想不出一个办法来使用原生的PySparkian。where(col(bar).isin(baz)) 自从 baz 在这种情况下,将不得不是一个列表。

我想到的一个方案是 right JOIN 作为替代IN和 left_semi JOIN 作为NOT IN的替代,请看下面的例子。

bar_where_foo_is_in_baz = bar.join(bar.select('baz').alias('baz_'), col('foo') == col('baz_'), 'right').drop('baz_')

然而,这是很啰嗦的,读了一会儿就很难理解,而且在处理更多的条件时,会导致相当多的头疼。WHERE 所以我想避免这种情况。

还有其他选择吗?

EDIT(请阅读)。

由于我似乎误导了不少答案 我的具体要求是将 "WHERE - IN "子句翻译成PySpark,而不需要用到... .collect() 或一般情况下,映射到Pythonic list(如内部函数 .isin() 会要求我)。)

sql pyspark where-in
1个回答
0
投票

从Jacek Laskowski的 GitBook

Spark SQL使用 广播加盟 (也就是广播式哈希连接),而不是哈希连接,以优化连接查询,当一方数据的大小低于 spark.sql.autoBroadcastJoinThreshold

广播式加盟可以非常有效地实现 在一个大表(事实)与相对小表(尺寸)之间进行连接 ,然后可以用来执行星型连接。它可以避免通过网络发送大表的所有数据。

而且

Spark SQL 2.2支持使用广播标准函数或SQL注释的BROADCAST提示。

  • SELECT /*+ MAPJOIN(b) */ …​
  • SELECT /*+ BROADCASTJOIN(b) */ …​
  • SELECT /*+ BROADCAST(b) */ …​

实际上 Spark文档 是比较全面的提示。

BROADCAST提示引导Spark在将每个指定的表与另一个表或视图连接时,对它们进行广播。当Spark决定连接方式时,优先选择广播哈希连接(即BHJ),即使统计量高于配置的 spark.sql.autoBroadcastJoinThreshold.

当一个连接的两边都被指定时,Spark会广播统计量较低的那一边。注意Spark并不保证总是选择BHJ,因为并不是所有的情况下(比如全外联接)都支持BHJ。


最后,如果你认真地开发高效的Spark作业,你应该花一些时间来了解这个野兽是如何工作的。

比如说那个 关于Databricks的连接的介绍 应有帮助

© www.soinside.com 2019 - 2024. All rights reserved.