Scala 火花检测笛卡尔积,尽管连接条件是非平凡的

Scala 火花检测笛卡尔积,尽管连接条件是非平凡的,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,我使用的是Spark 2.3.0,我有两个数据帧 第一个是df1,其模式为: root |-- time: long (nullable = true) |-- channel: string (nullable = false) root |-- pprChannel: string (nullable = true) |-- ppr: integer (nullable = false) 第二个是df2,其模式为: root |-- time: long (nullable =

我使用的是Spark 2.3.0,我有两个数据帧

第一个是df1,其模式为:

root
 |-- time: long (nullable = true)
 |-- channel: string (nullable = false)
root
 |-- pprChannel: string (nullable = true)
 |-- ppr: integer (nullable = false)
第二个是df2,其模式为:

root
 |-- time: long (nullable = true)
 |-- channel: string (nullable = false)
root
 |-- pprChannel: string (nullable = true)
 |-- ppr: integer (nullable = false)
我现在试着做:

spark.sql("select a.channel as channel, a.time as time, b.ppr as ppr from df1 a inner join df2 b on a.channel = b.pprChannel")
但我得到了逻辑计划之间内部联接的
检测笛卡尔积

当我尝试用
sc.parallelize
和简单的seq在Spark Shell上重新创建时,它是有效的

这里可能出了什么问题

改善效果追踪 下面是我使用
df1时得到的结果。join(df2,'channel=='pprChannel,“inner”)。explain(true)

是的,
df1
是一个相当复杂的计算结果,这就是它如此庞大的原因
df2
是一个非常小的DF,它总是来自
Map
,最多有50到100个条目通过
sc触发。parallelize
。因此,我可以使用
crossJoin
where
作为解决方法。但我想理解为什么Spark认为它是笛卡尔积

后续行动2 我现在使用一种不同的方法。由于第一个DF是一个庞大的DF,它是复杂计算的结果,而第二个DF总是源自一个小地图,因此我将算法更改为使用普通的
map
操作来实现它:

val bDF2Data = sc.broadcast(df2Data)
val res =
  df1.
    as[(Long, String)].
    mapPartitions { iter =>
      val df2Data = bDF2Data.value
      iter.
        flatMap {
          case (time, channel) =>
            df2Data.get(channel).map(ppr => (time, channel, ppr))
        }
    }.
    toDF("time", "channel", "ppr").
    // More operations ...

也许这会有所帮助:不幸的是,我无法从
解释中找出问题所在。我添加了
explain
的输出作为编辑。