在 Spark 中,explain
是分析 SQL 或 DataFrame 执行计划的核心工具,通过不同模式可展示查询优化和执行的详细信息,默认情况下,这个语句只提供关于物理计划的信息。以下是具体使用方法及不同模式的作用:
1. explain
的基本语法
在 Spark 3.0 及以上版本,explain
支持多种模式参数,通过 mode
指定输出格式:
# DataFrame 调用方式
df.explain(mode="simple")
# SQL 调用方式
spark.sql("SELECT ...").explain("formatted")
# Spark-SQL 调用方式
EXPLAIN [ EXTENDED | CODEGEN | COST | FORMATTED ] statement
2. 不同模式详解
(1) simple
模式
- 用途:仅展示物理执行计划(Physical Plan),即 Spark 最终在集群上执行任务的具体步骤。
- 示例输出:
== Physical Plan == *(3) Project [name#1, price#2] +- *(3) Filter (id#0 = 2) +- LocalTableScan [id#0, name#1, price#2]
- 适用场景:快速查看查询的物理操作(如过滤、JOIN 类型、Shuffle 等)。
(2) extended
模式
- 用途:生成四种计划:解析后的逻辑计划(parsed logical plan)、分析后的逻辑计划(analyzed logical plan)、优化后的逻辑计划(optimized logical plan)和物理计划(physical plan)。。
- 输出结构:
- 解析计划:解析后的逻辑计划是从查询中提取出来的未解析的计划。它是一个初步的计划,还没有进行任何解析或分析,只是从原始查询中提取出来的结构。
- 逻辑计划:未经优化的逻辑操作(如
Filter
、Join
),分析后的逻辑计划会进行转换,将未解析的属性(unresolvedAttribute
)和未解析的关系(unresolvedRelation
)转换为完全类型化的对象。这意味着在这个阶段,系统会解析查询中的各种元素,确定它们的类型和关系,从而生成一个更完整的逻辑计划。 - 优化后的逻辑计划:优化后的逻辑计划会通过一系列优化规则进行转换,最终生成物理计划。在这个阶段,系统会对逻辑计划进行优化,以提高查询的执行效率。优化规则可能包括选择更高效的算法、调整查询的执行顺序等,Catalyst 优化器应用规则后的结果(如谓词下推、列裁剪)。
- 物理计划:最终生成的物理计划是一个具体的执行计划,描述了如何在物理存储上执行查询。
- 适用场景:对比优化前后的差异,定位优化是否生效。
(3) codegen
模式
- 用途:展示由 Spark 生成的 Java 代码(Code Generation),用于加速计算(如循环展开、向量化操作)。
- 示例输出:
/* 001 */ public Object generate(Object[] references) { /* 002 */ // 生成的代码片段... /* 003 */ }
- 适用场景:分析代码生成效率或排查 Codegen 相关问题。
(4) cost
模式
- 用途:如果计划节点的统计信息是可用的,那么就会生成一个逻辑计划以及这些统计信息。这里的“计划节点的统计信息”可能指的是关于数据分布、数据量等有助于优化查询执行的信息。如果这些信息存在,系统会基于它们来生成逻辑计划,并且还会提供这些统计信息的细节,这有助于进一步分析和优化查询性能。(如
ANALYZE TABLE
)。 - 适用场景:基于统计信息优化复杂查询(如 JOIN 顺序选择)。
(5) formatted
模式
- 用途:以结构化分隔符展示物理计划,包含节点详细信息(如输入输出字段、分区策略)。
- 示例输出:
== Physical Plan == * HashAggregate (5) +- Exchange (4) +- * HashAggregate (3) +- * Project (2) +- * Filter (1) +- LocalTableScan [id, name, price]
- 适用场景:提高物理计划的可读性,快速定位性能瓶颈(如 Shuffle 开销)帮助用户从宏观上把握物理计划的执行流程,为后续深入分析和理解物理计划提供一个基础框架,便于快速定位和理解物理计划中的关键环节。
3. 执行计划的核心阶段
通过 explain
可观察查询在 Spark 内部的处理流程:
- Unresolved 逻辑计划:语法解析后的初始计划,未验证表名和字段(如
UnresolvedRelation
)。 - Resolved 逻辑计划:通过 Catalog 验证元数据(如表是否存在、字段类型)。
- 优化后的逻辑计划:应用优化规则(如谓词下推、常量折叠)。
- 物理计划:转换为具体执行操作(如
BroadcastHashJoin
、Exchange
)。
4. 最佳实践
- 优化查询:优先使用
formatted
或extended
模式,分析 Shuffle(Exchange
)和 JOIN 类型(如SortMergeJoin
是否可替换为BroadcastJoin
)。 - 调试问题:通过
codegen
检查生成的代码是否高效,或通过cost
模式验证统计信息是否准确。 - 结合 Spark UI:在图形化界面中对照物理计划,观察任务执行详情(如各阶段耗时)。
通过灵活使用 explain
的不同模式,可以深入理解查询执行机制,并针对性地优化性能瓶颈。