Spark 中的 Join 和 withColumn 异常

Posted

技术标签:

【中文标题】Spark 中的 Join 和 withColumn 异常【英文标题】:Exception with Join and withColumn in Spark 【发布时间】:2019-01-21 18:41:00 【问题描述】:

我正在尝试加入以下 2 个数据框:

val df1 = Seq(
      ("Verizon", "USA"),
      ("AT & T", "PK"),
      ("Verizon", "IND")
    ).toDF("Brand", "Country")

    val df2 = Seq(
      (8, "USA"),
      (64, "UK"),
      (-27, "DE")
    ).toDF("TS", "Country")

如果我这样加入,它会起作用:

df1.join(df2, Seq("Country")).count

但是当我尝试在加入之前使用 withColumn()lit() (替换列值)时,它会引发异常:

df1.withColumn("Country", lit("USA")).join(df2, Seq("Country")).count

例外:

org.apache.spark.sql.AnalysisException: Detected implicit cartesian product for INNER join between logical plans
LocalRelation
and
Project
+- Filter (isnotnull(_2#680) && (USA = _2#680))
   +- LocalRelation [_1#679, _2#680]
Join condition is missing or trivial.
Either: use the CROSS JOIN syntax to allow cartesian products between these
relations, or: enable implicit cartesian products by setting the configuration
variable spark.sql.crossJoin.enabled=true;
  at org.apache.spark.sql.catalyst.optimizer.CheckCartesianProducts$$anonfun$apply$21.applyOrElse(Optimizer.scala:1124)
  at org.apache.spark.sql.catalyst.optimizer.CheckCartesianProducts$$anonfun$apply$21.applyOrElse(Optimizer.scala:1121)
  at org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$2.apply(TreeNode.scala:267)
  at org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$2.apply(TreeNode.scala:267)
  at org.apache.spark.sql.catalyst.trees.CurrentOrigin$.withOrigin(TreeNode.scala:70)
  at org.apache.spark.sql.catalyst.trees.TreeNode.transformDown(TreeNode.scala:266)
   ...

当我使用crossjoin时它也有效:

df1.withColumn("Country", lit("USA")).crossJoin(df2.filter(col("Country") === "USA"))

但我不明白为什么它不适用于简单的join。为什么我需要使用 cross join 来使其工作。任何帮助,将不胜感激。谢谢

【问题讨论】:

Detected cartesian product for INNER join on literal column in PySpark的可能重复 那个和排序合并连接有关。不是。 在加入之前设置 sql("set spark.sql.crossJoin.enabled=true") 对我有用。但不知道为什么它会起作用。 【参考方案1】:

当您打算使用内部联接时,Spark 分析器检测到交叉联接条件。

由于交叉连接的成本很高,因此当物理计划检测到查询未明确使用交叉连接的交叉连接状态时,默认行为会引发异常。

这是由于由文字形成的替换列造成的。

Cross join behavior explanation 在 user10465355 提到的线程中有更详细的解释。

【讨论】:

这是我的问题,为什么我会得到交叉连接异常。这是什么原因? 这是由于由文字 'USA' 形成的替换列而发生的。因此,如果您使用由该类型列形成的列进行内部连接,您将遇到此异常。这是分析器中的简单规则验证 所以你的意思是说,带有点亮列的数据框不适用于连接?如果是,那么在不使用交叉连接的情况下使用 lit 连接的正确方法是什么,因为它是昂贵的操作。 它很贵,所以如果你还想使用它。使用使用交叉连接语法。根据我们的用例,如果我们必须进行交叉连接,我们会使用交叉连接,因此分析器知道您打算使用交叉连接并且不会抱怨。 但我不想使用交叉连接。有没有其他方法可以解决这个问题?

以上是关于Spark 中的 Join 和 withColumn 异常的主要内容,如果未能解决你的问题,请参考以下文章

Spark SQL中的broadcast join分析

Spark SQL中的broadcast join分析

Spark SQL中的broadcast join分析

spark outer join push down filer rule(spark 外连接中的下推规则)

spark outer join push down filter rule(spark 外连接中的下推规则)

Spark2 DataFrameStatFunctions探索性数据统计分析