如何在sparkDataframe上应用部分排序?

uemypmqf  于 2021-05-27  发布在  Spark
关注(0)|答案(2)|浏览(501)

以下代码:

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 call及其实现 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]
yhxst69z

yhxst69z1#

mydf.orderby(“number”).limit(3).显示
mydf.limit(3).orderby(“数字”).show
1=>将执行完全排序,然后选择前3个元素。
2=>将返回包含前3个元素的Dataframe并排序。

neekobn8

neekobn82#

如果你 explain() 在您的Dataframe中,您会发现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]

我认为在优化的逻辑计划部分可以看到最好的结果,但是物理上也说了同样的事情。

相关问题