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 outer join push down filer rule(spark 外连接中的下推规则)