我创建了一个Spark Dataset[Long]
:
scala> val ds = spark.range(100000000)
ds: org.apache.spark.sql.Dataset[Long] = [id: bigint]
当我运行ds.count
时,它给我的结果是0.2s
(在4核8GB机器上)。此外,它创建的DAG如下所示:
但是,当我运行ds.rdd.count
时,它给我的结果是4s
(同一台机器)。但它创建的DAG如下:
所以,我的疑虑是:
1.为什么ds.rdd.count
只创建一个阶段,而ds.count
创建两个阶段?
1.另外,当ds.rdd.count
只有一个阶段时,为什么它比有两个阶段的ds.count
慢?
2条答案
按热度按时间ruarlubt1#
为什么ds.rdd.count只创建一个阶段,而ds.count创建两个阶段?
两个计数实际上是两步操作。不同之处在于,在
ds.count
的情况下,最终聚合由执行器之一执行,而ds.rdd.count
聚合驱动程序上的最终结果,因此该步骤未反映在DAG中:另外,当
ds.rdd.count
只有一个阶段时,为什么它会更慢同样,
ds.rdd.count
必须初始化(以及稍后的垃圾收集)1亿个Row
对象,这几乎不是免费的,可能是这里大部分时间差的原因。最后,类
range
对象不是一个好的基准测试工具,除非非常谨慎地使用。根据上下文计数,范围内的操作可以表示为常数时间操作,即使没有显式优化也可以非常快(例如,参见spark.sparkContext.range(0, 100000000).count
),但不能反映真实的工作负载的性能。标签:How to know which count query is the fastest?
uwopmtnx2#
Spark 3.3.0新增
如果此DataFrame为空,则返回True。
https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.DataFrame.isEmpty.html