假设以下查询:
select * from my_table
Spark的哪个部分解析sql并创建执行计划?
Spark SQL执行引擎是否有自己的sql解析器将其转换为自己的执行模型?它是如何工作的?
我的一些函数异常,但是spark还不支持它们,是否意味着火花解析sql查询?彼此的执行引擎也做了吗?
答案 0 :(得分:11)
在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)