искровое перекрестное соединение, два одинаковых кода, один работает, другой нет - PullRequest
0 голосов
/ 28 сентября 2018

У меня есть следующий код:

val ori0 = Seq(
  (0l, "1")
).toDF("id", "col1")
val date0 = Seq(
  (0l, "1")
).toDF("id", "date")

val joinExpression = $"col1" === $"date"
ori0.join(date0, joinExpression).show()

val ori = spark.range(1).withColumn("col1", lit("1"))
val date = spark.range(1).withColumn("date", lit("1"))
ori.join(date,joinExpression).show()

Первое объединение работает, но второе имеет ошибку:

Exception in thread "main" org.apache.spark.sql.AnalysisException: Detected implicit cartesian product for INNER join between logical plans
Range (0, 1, step=1, splits=Some(4))
and
Project [_1#11L AS id#14L, _2#12 AS date#15]
+- Filter (isnotnull(_2#12) && (1 = _2#12))
   +- LocalRelation [_1#11L, _2#12]
Join condition is missing or trivial.

Я смотрю это много раз, я делаюНе знаю, почему это перекрестное соединение, и в чем разница между ними?

1 Ответ

0 голосов
/ 28 сентября 2018

Если бы вы развернули второе объединение, вы бы увидели, что оно действительно эквивалентно:

SELECT * 
FROM ori JOIN date
WHERE 1 = 1

Ясно WHERE 1 = 1 Условие соединения тривиально, что является одним из условий, при которых Spark обнаруживает декартово.

В первом случае это не так, потому что в этот момент оптимизатор не может сделать вывод, что столбцы объединения содержат только одно значение, и попытается применить хеш-соединение или сортировку слиянием.

...