spark join 引发“检测到 INNER 连接的笛卡尔积”

Posted

技术标签:

【中文标题】spark join 引发“检测到 INNER 连接的笛卡尔积”【英文标题】:spark join raises "Detected cartesian product for INNER join" 【发布时间】:2017-02-10 08:12:08 【问题描述】:

我有一个数据框,我想为每一行添加 new_col=max(some_column0) 由其他一些 column1 分组:

maxs = df0.groupBy("catalog").agg(max("row_num").alias("max_num")).withColumnRenamed("catalog", "catalogid")
df0.join(maxs, df0.catalog == maxs.catalogid).take(4)

在第二个字符串中我得到一个错误:

AnalysisException: u'Detected cartesian product for INNER join between 逻辑计划\nProject ... 使用 CROSS JOIN 语法允许 这些关系之间的笛卡尔积。;'

我不明白什么:为什么 spark 在这里找到笛卡尔积?

获得此错误的一种可能方法:我将 DF 保存到 Hive 表,然后再次初始化 DF 作为从表中选择。或者用 hive 查询替换这两个字符串 - 无论如何。但是我不想保存DF。

【问题讨论】:

【参考方案1】:

如Why does spark think this is a cross/cartesian join所述,可能是由于:

发生这种情况是因为您加入了共享相同血统的结构,这导致了微不足道的平等条件。

至于笛卡尔积是如何产生的?可以参考Identifying and Eliminating the Dreaded Cartesian Product。

【讨论】:

最好在答案本身中包含所有相关信息,而不仅仅是在链接中 - 链接可能会失效,但答案文本不会(希望如此)【参考方案2】:

我在加入时遇到了与笛卡尔积相同的问题。 为了克服它,我在 DataFrames 上使用了别名。看例子

from pyspark.sql.functions import col

df1.alias("buildings").join(df2.alias("managers"), col("managers.distinguishedName") == col("buildings.manager"))

【讨论】:

它似乎可以在 Pyspark 中使用 alias ,但在 scala 数据框 API 中,它不起作用【参考方案3】:

尝试在加入数据帧之前对其进行持久化。为我工作。

【讨论】:

以上是关于spark join 引发“检测到 INNER 连接的笛卡尔积”的主要内容,如果未能解决你的问题,请参考以下文章

Spark中的join策略

大数据开发-Spark Join原理详解

spark join

6000字总结Spark的5种join策略(建议收藏)

4,Spark中 join的原理

每个 Spark 工程师都应该知道的五种 Join 策略