【发布时间】:2017-05-29 20:20:54
【问题描述】:
假设以下查询:
select * from my_table
Spark 的哪一部分解析 sql 并创建执行计划?
Spark SQL 执行引擎是否有自己的 sql 解析器,可以将其转换为自己的执行模型?它是如何工作的?
我对一些 spark 不支持的函数有异常,这是否意味着 spark 解析 sql 查询?其他执行引擎也会这样做吗?
【问题讨论】:
标签: apache-spark apache-spark-sql
假设以下查询:
select * from my_table
Spark 的哪一部分解析 sql 并创建执行计划?
Spark SQL 执行引擎是否有自己的 sql 解析器,可以将其转换为自己的执行模型?它是如何工作的?
我对一些 spark 不支持的函数有异常,这是否意味着 spark 解析 sql 查询?其他执行引擎也会这样做吗?
【问题讨论】:
标签: apache-spark apache-spark-sql
在 Spark SQL 中,AstBuilder 构建了逻辑运算符和表达式的抽象语法树。
AstBuilder 将 ANTLR4 ParseTree 转换为催化剂
Expression、LogicalPlan或TableIdentifier。
AstBuilder 是一个 基于 ANTLR 的 SQL 解析器,它使用 SqlBase.g4 中描述的 SQL 语法(顺便从 Facebook 的 Presto 借用,额外支持 Hive 和 PostgreSQL 语句)。
您可以使用SparkSession.sql 处理支持的查询:
sql(sqlText: String): DataFrame 使用 Spark 执行 SQL 查询,将结果作为 DataFrame 返回。用于 SQL 解析的方言可以通过 'spark.sql.dialect' 进行配置。
您可以进入低级并直接使用解析器:
import spark.sessionState.sqlParser
scala> :type sqlParser
org.apache.spark.sql.catalyst.parser.ParserInterface
使用接受 SQL 文本的parsePlan 方法(在其他解析方法中)。
scala> sqlParser.parsePlan("select * from myTable")
res1: org.apache.spark.sql.catalyst.plans.logical.LogicalPlan =
'Project [*]
+- 'UnresolvedRelation `myTable`
使用逻辑计划(用于 SQL)Spark SQL 使用我称之为结构化查询执行管道(又名QueryExecution)的东西:
QueryExecution 使用 Spark 执行关系查询的主要工作流程。旨在让开发人员轻松访问查询执行的中间阶段。
每个Dataset 都有自己的QueryExecution,您可以使用queryExecution 属性访问:
val q = spark.range(5)
val qe = q.queryExecution
您可以使用analyzed、withCachedData、optimizedPlan、sparkPlan、executedPlan、toRdd 访问查询执行的各个阶段,这些惰性值都使用 explain 运算符一起显示。
scala> q.explain(extended = true)
== Parsed Logical Plan ==
Range (0, 5, step=1, splits=Some(8))
== Analyzed Logical Plan ==
id: bigint
Range (0, 5, step=1, splits=Some(8))
== Optimized Logical Plan ==
Range (0, 5, step=1, splits=Some(8))
== Physical Plan ==
*Range (0, 5, step=1, splits=8)
【讨论】: