Apache Spark 启动SEMI/ANTI JOIN作为布尔测试

7nbnzgx9  于 2023-02-19  发布在  Apache
关注(0)|答案(1)|浏览(126)

bounty将于明天到期。回答此问题可获得+100的声望奖励。wrschneider希望引起更多人关注此问题:希望在Spark中有更好的方法来做到这一点。

在Spark SQL中,有没有一种方法可以将SEMI JOIN或ANTI JOIN作为布尔测试来执行?
我经常有类似于
case when [not] exists(select 1 from ... subquery) then 1 else 0 end
SEMI和ANTI JOIN不是我想要的-我不想要WHERE [NOT] EXISTS,我想要SELECT中的CASE WHEN EXISTS
我能做的最好的事情就是

SELECT case when b.id is [not] null then 1 else 0 end as exists_flag
FROM a
LEFT JOIN b on a.id = b.id

但这并不好,原因有二

  • 必须担心重复-可能需要在连接之前进行“distinct”或聚合(不必担心EXISTS重复)
  • 别名-在结果集中以多个同名列结束;如果需要区分www.example.com,我无法执行自然连接a.id/b.id

有没有更好的办法?

gmxoilav

gmxoilav1#

SEMI和ANTI JOIN的UNION不是具有相同的语义吗?看起来很野蛮,但很容易理解:-)

SELECT *, 1 as exists_flag
FROM a LEFT SEMI JOIN b ON a.id = b.id
UNION
SELECT *, 0 as exists_flag
FROM a LEFT ANTI JOIN b ON a.id = b.id

如果您设法广播b(仅限b.ids!),性能方面可能不会太糟糕,如果不是,我非常肯定一个shuffle将被两个join重用,UNION将允许两个sort-merges并行运行,因此即使这样性能也不会太差。

相关问题