【问题标题】:Detected implicit cartesian product for INNER join between logical plan检测到逻辑计划之间的 INNER 连接的隐式笛卡尔积
【发布时间】:2023-03-08 19:03:01
【问题描述】:

我正在尝试加入两个数据集

Ds1

+-------------+-----------------+-----------+
|  countryName|countryPopulation|countrySize|
+-------------+-----------------+-----------+
|        China|       1210004992|    9596960|
|        India|        952107712|    3287590|
| UnitedStates|        266476272|    9372610|
|    Indonesia|        206611600|    1919440|
|       Brazil|        162661216|    8511965|
|       Russia|        148178480|   17075200|
|     Pakistan|        129275664|     803940|
|        Japan|        125449704|     377835|
|   Bangladesh|        123062800|     144000|
|      Nigeria|        103912488|     923770|
|       Mexico|         95772464|    1972550|
|      Germany|         83536112|     356910|
|  Philippines|         74480848|     300000|
|      Vietnam|         73976976|     329560|
|         Iran|         66094264|    1648000|
|        Egypt|         63575108|    1001450|
|       Turkey|         62484480|     780580|
|     Thailand|         58851356|     514000|
|UnitedKingdom|         58489976|     244820|
|       France|         58317448|     547030|
+-------------+-----------------+-----------+

Ds2:

+------------+-----------------+-----------+
| countryName|countryPopulation|countrySize|
+------------+-----------------+-----------+
|       China|       1210004992|    9596960|
|       India|        952107712|    3287590|
|UnitedStates|        266476272|    9372610|
|   Indonesia|        206611600|    1919440|
|      Brazil|        162661216|    8511965|
|      Russia|        148178480|   17075200|
|    Pakistan|        129275664|     803940|
|       Japan|        125449704|     377835|
|  Bangladesh|        123062800|     144000|
|     Nigeria|        103912488|     923770|
|     Germany|         83536112|     356910|
|     Vietnam|         73976976|     329560|
|        Iran|         66094264|    1648000|
|    Thailand|         58851356|     514000|
|      France|         58317448|     547030|
|       Italy|         57460272|     301230|
|    Ethiopia|         57171664|    1127127|
|     Ukraine|         50864008|     603700|
|       Zaire|         46498540|    2345410|
|       Burma|         45975624|     678500|
+------------+-----------------+-----------+

当我执行以下操作时,我得到输出

  Dataset<Row> ds3 = ds2.filter(ds2.col("countryPopulation").cast("int").$greater(100000))
        .join(ds1, ds1.col("countrySize")
                .equalTo(ds2.col("countrySize")));
  ds3.show();

但是当我执行以下操作时,我得到了错误

  Dataset<Row> ds3 = ds2.filter(ds2.col("countryPopulation").cast("int").$greater(100000))
        .join(ds1, ds1.col("countrySize").cast(DataTypes.IntegerType)
                .equalTo(ds2.col("countrySize").cast(DataTypes.IntegerType)), "inner");
  ds3.show();

错误:

Exception in thread "main" org.apache.spark.sql.AnalysisException: Detected implicit cartesian product for INNER join between logical plans
Project [country#6.name AS countryName#2, country#6.population AS countryPopulation#3, country#6.area AS countrySize#4]
+- Filter (isnotnull(country#6) && (Contains(country#6.name, a) && ((cast(country#6.population as int) > 100000) && (cast(country#6.area as int) = cast(country#6.area as int)))))
   +- Generate explode(countries#0.country), [0], false, t, [country#6]
      +- Relation[countries#0] json

请问应该如何同时投射和加入..?为什么会出现这个错误..?

这个“检测到逻辑计划之间的 INNER join 的隐式笛卡尔积”错误是什么意思?

【问题讨论】:

  • 你能用 cast("int") 代替 .cast(DataTypes.IntegerType)。
  • @Nikk,试过了..它给出了同样的错误。
  • 同一列名可能有冲突。您可以在为列别名后尝试:ds1.col("countrySize").cast(DataTypes.IntegerType).alias("size1").equalTo(ds2.col("countrySize").cast(DataTypes.IntegerType).alias("size2"):
  • @Gsquare,不..它给出了同样的错误。
  • 你能试试 Dataset ds3 = ds2.filter(ds2.col("countryPopulation").cast("int").$greater(100000)) .join(ds1, ds1. col("countrySize").cast("int") .equalTo(ds2.col("countrySize").cast("int")));

标签: java apache-spark apache-spark-sql


【解决方案1】:

我已经看到当 where 条件包含带有来自两个数据帧的参数的函数调用时,会发生笛卡尔连接。像df1.join(df2, aFunction(df1.column, df2.column) 这样的东西。在这里,我看不到确切的内容,但我怀疑正在发生类似的事情。

试试下面的方法,让函数应用在选择条件而不是位置上。

    Dataset<Row> ds1_1 = ds1.select(col("countrySize").cast(DataTypes.IntegerType).as("countrySize")) // add all columns here

    Dataset<Row> ds2_1 = ds2.select(col("countrySize").cast(DataTypes.IntegerType).as("countrySize"),ds2.col("countryPopulation").cast("int").as("countryPopulation")) // add all columns here

    Dataset<Row> ds3 = ds2.filter(ds2_1.col("countryPopulation").$greater(100000))
        .join(ds1_1, ds1_1.col("countrySize")
                .equalTo(ds2_1.col("countrySize")), "inner");
    ds3.show();

【讨论】:

  • 在您的最后一个数据集 ds3 中,您正在过滤来自 ds2 的数据,但加入 ds1_1 和 ds2_1 ...为什么会这样 ....?
  • 我只是复制粘贴了你的代码,我唯一添加的是在选择而不是连接条件中应用强制转换函数。根据需要更改代码,只需避免在 join 子句中调用函数。如果可行,请点赞。
猜你喜欢
  • 1970-01-01
  • 2017-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-16
  • 2011-11-11
  • 1970-01-01
相关资源
最近更新 更多