【发布时间】:2017-10-06 05:01:45
【问题描述】:
我一直在探索最近版本的 Spark SQL 2.3.0-SNAPSHOT 中的查询优化,并注意到语义相同查询的不同物理计划。
假设我必须计算以下数据集中的行数:
val q = spark.range(1)
我可以按如下方式计算行数:
q.countq.collect.sizeq.rdd.countq.queryExecution.toRdd.count
我最初的想法是,它几乎是一个恒定的操作(肯定是由于本地数据集),以某种方式已被 Spark SQL 优化并立即给出结果,尤其是。第一个 Spark SQL 完全控制查询执行。
看过查询的物理计划后,我相信最有效的查询将是最后一个:
q.queryExecution.toRdd.count
原因是:
- 它避免了从
InternalRow二进制格式反序列化行 - 查询是代码生成的
- 只有一个工作有一个阶段
物理计划就是这么简单。
我的推理正确吗?如果是这样,如果我从外部数据源(例如文件、JDBC、Kafka)读取数据集,答案会有所不同吗?
主要问题是要考虑哪些因素来判断查询是否比其他查询更有效(根据此示例)?
完整性的其他执行计划。
q.count
q.collect.size
q.rdd.count
【问题讨论】:
-
您是如何获得这些带有附加参数(行数等)的 DAG 图形的,从未见过。这是 spark 2.3 中的新功能吗?
-
@JacekLaskowski 基准测试? :) 2 节点集群,10000000 行,10 次迭代 - 应该回答你的问题。您还可以启动 Java Mission Control 来测量 GC,在线代码编译
-
只是预感,但
q.count似乎是这里唯一合理的选择。这是唯一可以应用源特定优化的方法(Daniel Darabos 的相关问题:stackoverflow.com/q/40629435/1560062)。q.queryExecution.toRdd.count可能很快(毕竟它只是一个带有可变累加器的天真while,所以 JVM 应该喜欢它)但它完全不知道上下文。例如,如果你通过 JDBC 运行它,它只会获取所有行,而不是一堆。 -
@zero323 尽管如此。不在主界面上运行应用程序有什么好处吗?我认为我们不应该直接使用查询,而是通过数据集
-
你们都想要基准测试的任何其他“计数”方法吗?列出的 4 个不同数据大小(1M、1B、1T)、方法、数据源(范围、镶木地板、文本文件)的编译时间
标签: performance apache-spark query-optimization apache-spark-sql