Spark中sort和orderBy函数有什么区别?

38

spark DataFrame中sort和orderBy有什么区别?

scala> zips.printSchema
root
 |-- _id: string (nullable = true)
 |-- city: string (nullable = true)
 |-- loc: array (nullable = true)
 |    |-- element: double (containsNull = true)
 |-- pop: long (nullable = true)
 |-- state: string (nullable = true)

以下命令会产生相同的结果:

zips.sort(desc("pop")).show
zips.orderBy(desc("pop")).show
3个回答

40

OrderBy只是sort函数的别名。

来自Spark文档:

  /**
   * Returns a new Dataset sorted by the given expressions.
   * This is an alias of the `sort` function.
   *
   * @group typedrel
   * @since 2.0.0
   */
  @scala.annotation.varargs
  def orderBy(sortCol: String, sortCols: String*): Dataset[T] = sort(sortCol, sortCols : _*)

2
从Spark文档中可以看出,SORT BY和ORDER BY并不相同。https://spark.apache.org/docs/latest/sql-ref-syntax-qry-select-sortby.html 我有什么遗漏吗? - Fardin Abdi
4
我们必须正确分类以清楚地理解它。在Spark SQL中,order by会进行整体排序;sort by会进行分区排序。在Spark DataFrame API中,sort()和orderBy()会进行整体排序,而sortWithinPartitions()则会进行分区排序。 - Ankit Mahajan
3
但在pyspark中,我可以发现orderby只是sort函数的别名。https://github.com/apache/spark/blob/0c9c8ff56933e6ae13454845e831746360af84e3/python/pyspark/sql/dataframe.py#L1423 - Bharath Ram
3
即使在Scala中,orderby也是sort函数的别名。 https://github.com/apache/spark/blob/5d74ace648422e7a9bff7774ac266372934023b9/sql/core/src/main/scala/org/apache/spark/sql/Dataset.scala#L1306 - Bharath Ram

21

它们不是相同的。

SORT BY子句用于按照用户指定的顺序在每个分区内返回排序后的结果行。当存在多个分区时,SORT BY可能返回部分有序的结果。

参考:https://spark.apache.org/docs/latest/sql-ref-syntax-qry-select-sortby.html

ORDER BY子句用于按照用户指定的顺序以一种排序方式返回结果行。与SORT BY子句不同,此子句保证输出具有完全顺序。

参考:https://spark.apache.org/docs/latest/sql-ref-syntax-qry-select-orderby.html


3
如果是这样的话,使用“sort by”的真正用途是什么?我实际上还没有注意到多分区中的这种区别。 - ss301
3
在SQL API中,SORT BYORDER BY之间存在差异。问题出现在Scala API中,其中DataFrame方法sort()orderBy()实际上执行相同的操作。要执行SQL的SORT BY,Scala使用sortWithinPartitions()。PySpark API中也是如此。 - Melkor.cz

0

sort() 函数按照文件系统上给定列对每个存储桶中的输出进行排序。它不保证输出数据的顺序。

orderBy() 分两个阶段进行。

首先在每个存储桶内使用 sortBy() 进行排序,然后整个数据必须被带入单个执行器以根据指定列以升序或降序的方式获得总体顺序。这涉及大量的洗牌操作,是一项代价高昂的操作。但是由于

sort() 操作发生在每个单独的存储桶内并且是一项轻量级操作。

这里有一个例子:

准备数据

>>> listOfTuples = [(16,5000),(10,3000),(13,2600),(19,1800),(11,4000),(17,3100),(14,2500),(20,2000)]
>>> tupleRDD = sc.parallelize(listOfTuples,2)
>>> tupleDF = tupleRDD.toDF(["Id","Salary"])

数据看起来像这样:
>>> tupleRDD.glom().collect()
[[(16, 5000), (10, 3000), (13, 2600), (19, 1800)], [(11, 4000), (17, 3100), (14, 2500), (20, 2000)]]
>>> tupleDF.show()
+---+------+
| Id|Salary|
+---+------+
| 16|  5000|
| 10|  3000|
| 13|  2600|
| 19|  1800|
| 11|  4000|
| 17|  3100|
| 14|  2500|
| 20|  2000|
+---+------+

现在将进行排序操作。
>>> tupleDF.sort("id").show()
+---+------+
| Id|Salary|
+---+------+
| 10|  3000|
| 11|  4000|
| 13|  2600|
| 14|  2500|
| 16|  5000|
| 17|  3100|
| 19|  1800|
| 20|  2000|
+---+------+

看,顺序不如预期。现在如果我们看orderBy操作:
>>> tupleDF.orderBy("id").show()
+---+------+
| Id|Salary|
+---+------+
| 10|  3000|
| 11|  4000|
| 13|  2600|
| 14|  2500|
| 16|  5000|
| 17|  3100|
| 19|  1800|
| 20|  2000|
+---+------+

它保持数据的整体顺序。

19
我不明白你所说的“顺序与期望不符”的意思。在我看来,这两个输出看起来是一样的。 - Niranjan Viladkar
是的,我很困惑,这三个输出是相同的。 - Excel Help

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接