3

以下代码:

val myDF = Seq(83, 90, 40, 94, 12, 70, 56, 70, 28, 91).toDF("number")
myDF.orderBy("number").limit(3).show

输出:

+------+
|number|
+------+
|    12|
|    28|
|    40|
+------+

Spark 的懒惰与limit调用和orderBy自动实现的结合是否会导致部分排序的 DataFrame,或者剩余的 7 个数字是否也已排序,即使它不需要?如果是这样,有没有办法避免这种不必要的计算工作?


使用.explain()显示,执行两个排序阶段,首先在每个分区上,然后(每个前 3 个)一个全局阶段。但它没有说明这些种类是完整的还是部分的。

myDF.orderBy("number").limit(3).explain(true)
== Parsed Logical Plan ==
GlobalLimit 3
+- LocalLimit 3
   +- Sort [number#3416 ASC NULLS FIRST], true
      +- Project [value#3414 AS number#3416]
         +- LocalRelation [value#3414]

== Analyzed Logical Plan ==
number: int
GlobalLimit 3
+- LocalLimit 3
   +- Sort [number#3416 ASC NULLS FIRST], true
      +- Project [value#3414 AS number#3416]
         +- LocalRelation [value#3414]

== Optimized Logical Plan ==
GlobalLimit 3
+- LocalLimit 3
   +- Sort [number#3416 ASC NULLS FIRST], true
      +- LocalRelation [number#3416]

== Physical Plan ==
TakeOrderedAndProject(limit=3, orderBy=[number#3416 ASC NULLS FIRST], output=[number#3416])
+- LocalTableScan [number#3416]
4

2 回答 2

3

如果你是explain()你的数据框,你会发现 Spark 会首先在每个分区中进行“本地”排序,然后从每个分区中只选择前三个元素进行最终的全局排序,然后再取出前三个。

scala> myDF.orderBy("number").limit(3).explain(true)
== Parsed Logical Plan ==
GlobalLimit 3
+- LocalLimit 3
   +- Sort [number#3 ASC NULLS FIRST], true
      +- Project [value#1 AS number#3]
         +- LocalRelation [value#1]

== Analyzed Logical Plan ==
number: int
GlobalLimit 3
+- LocalLimit 3
   +- Sort [number#3 ASC NULLS FIRST], true
      +- Project [value#1 AS number#3]
         +- LocalRelation [value#1]

== Optimized Logical Plan ==
GlobalLimit 3
+- LocalLimit 3
   +- Sort [number#3 ASC NULLS FIRST], true
      +- LocalRelation [number#3]

== Physical Plan ==
TakeOrderedAndProject(limit=3, orderBy=[number#3 ASC NULLS FIRST], output=[number#3])
+- LocalTableScan [number#3]

我认为它在优化的逻辑计划部分中得到了最好的体现,但物理上也说了同样的话。

于 2020-07-26T18:14:17.400 回答
-1
  1. myDF.orderBy("number").limit(3).show
  2. myDF.limit(3).orderBy("number").show

1 => 将进行完整排序,然后选择前 3 个元素。

2 => 将返回具有前 3 个元素的数据框并进行排序。

于 2020-07-26T16:33:22.100 回答