我正在寻找一个快速的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()
会要求我)。)
从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。
比如说那个 关于Databricks的连接的介绍 应有帮助