Spark报错:Detected cartesian product for LEFT OUTER join between logical plans

[Spark报错]:Detected cartesian product for LEFT OUTER join between logical plans

FBI warning:xian si kao yao bu yao di ka er cha xun, If true Then return

注意:先思考一下自己sql语句是不是真的需要笛卡尔查询,如果是的话,本文跳过

开门见山

测试程序:

import java.util

import org.apache.spark.sql.{DataFrame, Row, SparkSession}
import org.apache.spark.sql.types.{IntegerType, StringType, StructField, StructType}

import scala.collection.JavaConverters._

object SparkTestJoin {
  def main(args: Array[String]): Unit = {
    val spark: SparkSession = SparkSession.builder().master("local[*]").getOrCreate()

    val java: util.List[Row] = List[Row](
      Row(1, "zhangsan", 86),
      Row(2, "lisi", 97),
      Row(3, "wangwu", 100)
    ).asJava

    val struct: StructType = StructType(Seq(
      StructField("id", IntegerType, true),
      StructField("name", StringType, true),
      StructField("score", IntegerType, true)
    ))
    
    val df1: DataFrame = spark.createDataFrame(java, struct)
    val df2:DataFrame= df1              //注意这里!
    
    df1.join(df2,df1("id")<=>df2("id"),"left").show(false)
    spark.stop()
  }
}

报错如下:
在这里插入图片描述
  看到了Exception in thread "main" org.apache.spark.sql.AnalysisException: Detected cartesian product for LEFT OUTER join between logical plans
对于这个错误,我搜索了一下,发现很多文章里面都是说要打开spark笛卡尔join的开关,就是进行如下操作啦:

"spark.sql.crossJoin.enabled", "true"  //可以写到config里面

我照着做了,然后我发现,程序虽然不报错了,但是执行起来很慢。不想等它执行完了。
我思考了一下,我的计算逻辑中,不应该存在笛卡尔交集的join操作,然后又经过一段时间的搜索。我发现有一个stackOverFlow里面提到了,spark将这个操作视作笛卡尔操作的原因:join的两张表具有相同的血缘关系原文章
在下面的很小一部分提到了这个问题的原因(仅供参考)


解决方案

在原文中提到了一种给待进行join操作的两边的DataFrame添加一个别名。这个操作,迷惑到我了。我试不出来。
既然是因为df1df2具有相同的血缘关系的话,那么是不是意味着我将这个血缘关系破坏掉就可以将这个问题解决了。

下面是我的解决方案:

解决方案1:

在这里插入图片描述
这样做的话,程序可以正常地跑通了。没有报错误。

解决方案2:

df1df2都注册成表,然后用SparkSQL 操作,像这样
在这里插入图片描述

结束语

我感觉SparkDSL的风格的SQL查询语言,比起SparkSQL语句还是有一些局限的,有些操作利用SparkDSL风格的SQL查询的话,非常不方便。。。。

如果看到这篇文章的大佬有什么更好的方法请在下面留言。谢谢。

发布了56 篇原创文章 · 获赞 7 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/OldDirverHelpMe/article/details/103929015