performance - 如何知道哪个计数查询最快?

标签 performance apache-spark query-optimization apache-spark-sql

我一直在最近的Spark SQL 2.3.0-SNAPSHOT版本中探索查询优化,并注意到了语义相同查询的不同物理计划。

假设我必须计算以下数据集中的行数:

val q = spark.range(1)

我可以按以下方式计算行数:
  • q.count
  • q.collect.size
  • q.rdd.count
  • q.queryExecution.toRdd.count

  • 我最初的想法是,它几乎是一个恒定的操作(肯定是由于本地数据集),它会以某种方式由Spark SQL优化,并且会立即给出结果,尤其是。第一个是Spark SQL完全控制查询执行的地方。

    看过查询的物理计划后,我相信最有效的查询将是最后一个:
    q.queryExecution.toRdd.count
    

    原因是:
  • 避免从其InternalRow二进制格式
  • 反序列化行
  • 查询是经过代码生成的
  • 单阶段只有一项工作

  • body 计划就这么简单。

    Details for Job

    我的推理正确吗?如果是这样,如果我从外部数据源(例如文件,JDBC,Kafka)读取数据集,答案会有所不同吗?

    主要问题是要考虑一个查询是否比其他查询更有效的因素(在此示例中)?

    其他执行计划的完整性。

    数量

    q.count

    q.collect.size

    q.collect.size

    q.rdd.count

    q.rdd.count

    最佳答案

    我对val q = spark.range(100000000)做了一些测试:

  • q.count:〜50毫秒
  • q.collect.size:一分钟左右后我停止了查询...
  • q.rdd.count:约1100毫秒
  • q.queryExecution.toRdd.count:〜600毫秒

  • 一些解释:

    到目前为止,选项1最快,因为它同时使用了部分聚合和整个阶段的代码生成。整个阶段的代码生成使JVM变得非常聪明,并进行了一些激烈的优化(请参阅:https://databricks.com/blog/2017/02/16/processing-trillion-rows-per-second-single-machine-can-nested-loop-joins-fast.html)。

    选项2。只是速度慢,并且使驱动程序上的所有内容具体化,这通常不是一个好主意。

    选项3与选项4类似,但是首先将内部行转换为常规行,这非常昂贵。

    选项4。在没有整个阶段代码生成的情况下,速度差不多。

    关于performance - 如何知道哪个计数查询最快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43843470/

    相关文章:

    c# - 修改字典值而不分配

    java - Java中的文件复制

    mysql - 使用昂贵的 INNER JOIN 优化 MySQL 查询

    mysql - SQL查询中年龄计算的性能

    excel - 我怎样才能加快循环

    python-3.x - 派斯帕克 : Pass dynamic Column in UDF

    scala - Spark DataFrame 中的 collectAsList

    apache-spark - JAVA 中的 Spark IntArrayParm

    mysql - 如何优化mysql查询: counting category and subcategory with single Query from two tables

    python - 加速 Cython 实现点积乘法