【问题标题】:Performance comparison with take(10) vs limit(10).collect()与 take(10) 与 limit(10).collect() 的性能比较
【发布时间】:2019-10-07 03:48:14
【问题描述】:

我有一个包含十亿条记录的数据框,我想从中取出 10 条记录。

哪种方法更好更快?

df.take(10)df.limit(10).collect()?

【问题讨论】:

    标签: scala dataframe apache-spark apache-spark-sql


    【解决方案1】:

    这两种方法将产生相同的性能,这仅仅是因为它们的实现是相同的

    来自 github 上的 Spark 实现

    def take(n: Int): Array[T] = head(n)
    

    虽然head的实现是:

    def head(n: Int): Array[T] = withAction("head", limit(n).queryExecution)(collectFromPlan)
    

    如您所见,head 正是使用limit+collect 实现的。

    因此它们的性能相同,您测量的差异必须是随机变化,尝试多次运行实验以克服它。

    【讨论】:

    • 它们的实现不一样,一个是“通过触发查询执行”
    • @lssilva 您应该将 take(i.e. head) 与 limit + collect 进行比较,limit 确实会返回一个新数据集,因为它不是一个动作
    • @lssilva a) 这个问题涉及 Python,而不是 Scala。 b) 这正是将 take(n) 替换为 limit+collect 的修复,检查拉取请求
    • 你是对的,过去他们似乎有不同的实现,但这个变化同步了它:github.com/apache/spark/commit/…
    【解决方案2】:

    Spark 进行惰性进化。因此,无论您使用哪个 API,两者都会为您提供相同的结果和相同的性能。

    【讨论】:

    • 所选择的物理查询计划与惰性评估与否无关。
    【解决方案3】:

    使用 take(10),它应该是瞬时的。

    myDataFrame.take(10) //Action
    df.limit(10) //Transformation
    

    参考:spark access first n rows - take vs limit

    【讨论】:

    • 但在我的情况下,我可以看到 df.limit(10).collect() 有点快。我的假设是从十亿条记录数据帧中提取(10)是一件具有挑战性的事情。但是将数据帧切割成 10 条记录并收集更好。
    • 而且还加了一个点..即使我们再次给 take(10) 它在内部使用 Limit(10) 和其他一些功能
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 2018-12-16
    • 1970-01-01
    • 2010-11-04
    • 2011-06-10
    • 2017-08-09
    • 1970-01-01
    相关资源
    最近更新 更多