目录

Debugging-Query-Execution

概述

debug 包的对象包含了很多 debugging 查询执行计划的工具方法,例如针对 Datasets 的详细查询计划分析。可以查看表一,本文主要讲述 debugdebugCodegen 两个方法。

/debugging-query-execution/img.png

debug 包对象在 org.apache.spark.sql.execution.debug 里,如果需要用到 debugdebugCodegen 方法,需要进行导入这个包。

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[_] 来添加 debugdebugCodegen 方法的。

1
2
3
4
implicit class DebugQuery(query: Dataset[_]) {
  def debug(): Unit = ...
  def debugCodegen(): Unit = ...
}

Debug Method

1
debug(): Unit

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;
...

参考资料

  1. spark-sql-debugging-query-execution
警告
本文最后更新于 2017年2月1日,文中内容可能已过时,请谨慎参考。