为什么Spark失败了"检测到的笛卡尔积用于逻辑计划之间的INNER连接"?

时间:2017-06-26 14:44:01

标签: scala apache-spark apache-spark-sql

我正在使用 Spark 2.1.0

当我执行以下代码时,我从Spark收到错误。为什么?如何解决?

#include <Rcpp.h>

// [[Rcpp::export]]
Rcpp::NumericVector dget_example(std::string file) {
    // Obtain environment containing function
    Rcpp::Environment base("package:base");

    // Make function callable from C++
    Rcpp::Function dget_r = base["dget"];

    // Call the function and receive its list output
    Rcpp::NumericVector res = dget_r(Rcpp::Named("file") = file);
    // Change the above data type depending on _X_ object.

    return res;
}

错误:

val i1 = Seq(("a", "string"), ("another", "string"), ("last", "one")).toDF("a", "b")
val i2 = Seq(("one", "string"), ("two", "strings")).toDF("a", "b")
val i1Idx = i1.withColumn("sourceId", lit(1))
val i2Idx = i2.withColumn("sourceId", lit(2))
val input = i1Idx.union(i2Idx)
val weights = Seq((1, 0.6), (2, 0.4)).toDF("sourceId", "weight")
weights.join(input, "sourceId").show

5 个答案:

答案 0 :(得分:23)

您可以在打开标志

后触发内部联接
spark.conf.set("spark.sql.crossJoin.enabled", "true")

您也可以使用交叉连接。

weights.crossJoin(input)

或将别名设置为

weights.join(input, input("sourceId")===weights("sourceId"), "cross")

您可以在2.1.1

中找到有关issue SPARK-6459的更多信息

由于您已经使用过2.1.1,因此该问题应该已修复。

希望这有帮助!

答案 1 :(得分:4)

tl; dr 升级到Spark 2.1.1。这是固定的Spark中的一个问题。

(我真的希望我也能告诉你在2.1.1中确定的确切变化)

答案 2 :(得分:1)

对我来说

Dataset<Row> ds1 = sparkSession.read().load("/tmp/data");
Dataset<Row> ds2 = ds1;
ds1.join(ds2, ds1.col("name").equalTo(ds2.col("name"))) // got "Detected cartesian product for INNER join between logical plans"

Dataset<Row> ds1 = sparkSession.read().load("/tmp/data");
Dataset<Row> ds2 = sparkSession.read().load("/tmp/data");
ds1.join(ds2, ds1.col("name").equalTo(ds2.col("name"))) // running properly without errors

我正在使用Spark 2.1.0。

答案 3 :(得分:1)

在SPARK版本中得到此错误: 2.3.0.cloudera3

通过别名为数据框解决。

例如将失败的数据帧重新分配给另一个数据帧,并将名称别名给该另一个数据帧。

val dataFrame = inDataFrame.alias("dataFrame")

希望这会有所帮助。

答案 4 :(得分:1)

您可以在命令顶部使用它 设置spark.sql.crossJoin.enabled = TRUE;

如果您的查询很复杂,则可以重新构造查询以获得更好的结果