【问题标题】:Spark Dataset unique id performance - row_number vs monotonically_increasing_idSpark 数据集唯一 ID 性能 - row_number 与 monotonically_increasing_id
【发布时间】:2018-01-29 11:41:55
【问题描述】:
我想为我的数据集行分配一个唯一 ID。我知道有两种实现方案:
-
第一个选项:
import org.apache.spark.sql.expressions.Window;
ds.withColumn("id",row_number().over(Window.orderBy("a column")))
-
第二个选项:
df.withColumn("id", monotonically_increasing_id())
第二个选项不是顺序 ID,这并不重要。
我试图弄清楚这些实现是否存在任何性能问题。也就是说,如果此选项中的一个与另一个相比非常慢。更有意义的是:“monotonically_increasing_id 比 row_number 快,因为它不是顺序的或......”
【问题讨论】:
标签:
scala
apache-spark
apache-spark-sql
apache-spark-dataset
【解决方案1】:
monotically_increasing_id是分布式的,根据数据的partition执行。
而
row_number() 使用 Window 函数而不使用 partitionBy (如您的情况)未分发。当我们不定义partitionBy时,所有的数据都发送到一个执行器生成行号。
因此,可以肯定,monotically_increasing_id() 的性能将优于未定义 partitionBy 的 row_number()。
【解决方案2】:
TL;DR这甚至不是一场比赛。
从不使用:
row_number().over(Window.orderBy("a column"))
除了总结结果之外,已经适合单个机器内存的任何其他内容。
要在没有PARTITION BY 的情况下应用窗口函数,Spark 必须将所有数据洗牌到单个分区中。在任何大型数据集上,这只会使应用程序崩溃。顺序和不分布式甚至都无关紧要。