概述
debug
包的对象包含了很多 debugging 查询执行计划的工具方法,例如针对 Datasets
的详细查询计划分析。可以查看表一,本文主要讲述 debug
和 debugCodegen
两个方法。
debug
包对象在 org.apache.spark.sql.execution.debug
里,如果需要用到 debug
和 debugCodegen
方法,需要进行导入这个包。
1
2
3
4
5
6
7
|
// 导入相关的包
import org.apache.spark.sql.execution.debug._
// Dataset 和 DataFrame 都有这两个方法
val q: DataFrame = ...
q.debug
q.debugCodegen
|
debug
包是通过一个隐式类 DebugQuery
扩展 Dataset[_]
来添加 debug
和 debugCodegen
方法的。
1
2
3
4
|
implicit class DebugQuery(query: Dataset[_]) {
def debug(): Unit = ...
def debugCodegen(): Unit = ...
}
|
Debug Method
debug
要求 QueryExecution
优化过后的物理计划。debug
将优化后的物理查询计划增加一个新的 DebugExec
物理算子。debug
要求查询计划去运行然后计算行数在结果里。
1
|
Results returned: [count]
|
最后,debug
需要将每个 DebugExec
物理算子转化成一些统计信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
val q = spark.range(10).where($id === 4)
scala> :type q
org.apache.spark.sql.Dataset[Long]
// 给 Dataset[Long] 扩展 debug 和 debugCodegen 方法
import org.apache.spark.sql.execution.debug._
scala> q.debug
Results returned: 1
== WholeStageCodegen ==
Tuples output: 1
id LongType: {java.lang.Long}
== Filter (id#0L = 4) ==
Tuples output: 0
id LongType: {}
== Range (0, 10, step=1, splits=8) ==
Tuples output: 0
id LongType: {}
|
DebugCodegen Method
debugCodegen
方法要求查询优化过后的物理查询计划。该方法将“翻译”后的查询代码打印出来。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import org.apache.spark.sql.execution.debug._
scala> spark.range(10).where('id === 4).debugCodegen
Found 1 WholeStageCodegen subtrees.
== Subtree 1 / 1 ==
*Filter (id#29L = 4)
+- *Range (0, 10, splits=8)
// 产生的 code:
/* 001 */ public Object generate(Object[] references) {
/* 002 */ return new GeneratedIterator(references);
/* 003 */ }
/* 004 */
/* 005 */ final class GeneratedIterator extends org.apache.spark.sql.execution.BufferedRowIterator {
/* 006 */ private Object[] references;
...
|
参考资料
- spark-sql-debugging-query-execution
警告
本文最后更新于 2017年2月1日,文中内容可能已过时,请谨慎参考。