Jac*_*ski 7 performance query-optimization apache-spark apache-spark-sql
我一直在探索最近发布的Spark SQL 2.3.0-SNAPSHOT中的查询优化,并注意到语义相同查询的不同物理计划.
我们假设我必须计算以下数据集中的行数:
val q = spark.range(1)
Run Code Online (Sandbox Code Playgroud)
我可以按如下方式计算行数:
q.count
q.collect.size
q.rdd.count
q.queryExecution.toRdd.count
我最初的想法是它几乎是一个恒定的操作(肯定是由于本地数据集),它会以某种方式由Spark SQL优化并立即给出结果,尤其是.Spark SQL完全控制查询执行的第一个.
看了查询的物理计划后,我就相信最有效的查询将是最后一个:
q.queryExecution.toRdd.count
Run Code Online (Sandbox Code Playgroud)
原因是:
InternalRow
二进制格式反序列化行物理计划就这么简单.
我的推理是否正确?如果是这样,如果我从外部数据源(例如文件,JDBC,Kafka)读取数据集,答案会有所不同吗?
主要问题是,要考虑查询是否比其他查询更有效(在此示例中),需要考虑哪些因素?
其他执行计划是完整性的.
小智 9
我做了一些测试val q = spark.range(100000000)
:
q.count
:~50毫秒q.collect.size
:我在一分钟左右后停止了查询...q.rdd.count
:~1100 msq.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.如果没有整个阶段代码生成,您的速度会快得多.
归档时间: |
|
查看次数: |
4296 次 |
最近记录: |