Hive SQL编译过程

antlr介绍

Hive 使用 Antlr 实现 SQL 的词法和语法解析。Antlr 是一种语言识别工具,可以用来构造领域语言。Antrl 完成了词法分析、语法分析、语义分析、中间代码生成的过程。

Antrl 的工作方式:编写一个语法文件,构造特定规则的语法,定义语法和词法规则完成最终的替换,生成代码。

Hive 的语法规则和词法规则,都是定义在类似于 xxx.g 的文件中。其中:
0.10X 版本以前:一个统一的语法和词法文件 hive.g
0.11版本以后
	定义词法规则:HiveLexer.g
	定义语法规则:SelectClauseParser.g,FromClauseParser.g,IndentifiersParser.g,HiveParser.g

Hive 接收到用户编写的 HQL,通过 antlr 进行解析生成代码。

第一阶段:SQL 生成抽象语法树 ASTTree

antlr 对 Hive SQL 解析的代码如下,HiveLexerX,HiveParser 分别是 antlr 对语法文件 Hive.g 编译后自动生成的词法解析和语法解析类,在这两个类中进行负责的解析。

代码跳转关系:

CliDriver.main();
CliDriver.run();
CliDriver.executeDriver();
CliDriver.processLine()
CliDriver.processCmd()
CliDriver.processLocalCmd() # 完整的执行,输出过程
Driver.run()
Driver.runInternal() # 编译和执行
Driver.compileInternal() # 编译
Driver.compile() # 编译:SQL -> AST -> ResovleTree -> OperatorTree ->
TaskTree
ParseUtils.parse()
ParseDriver.parse()

image-20211101153418557

第二阶段:SQL 基本组成单元 QueryBlock

ASTTree 仍然非常复杂,不够结构化,不方便直接编译为 MapReduce 程序,ASTTree 转化为 QueryBlock 就是将 SQL 进一步抽象和结构化。

QueryBLock 是一条 SQL 最基本单元,包括三个部分:输入源、计算过程、输出。QueryBlock 可理解子查询,详细源代码:

org.apache.hadoop.hive.ql.parse.QB

ASTTree 生成 QueryBlock 的过程是一个递归的过程,先顺序遍历ASTTree,遇到不同的 Token 节点,保存到相应的属性中,主要包含一下几个过程:

  1. TOK_QUERY => 创建 QB 对象,循环递归子节点
  2. TOK_FROM => 将表名语法部分保存到 QB 对象的 aliasToTabs 等属性中
  3. TOK_INSERT => 循环递归子节点
  4. TOK_DESTINATION => 将输出目标的语法部分保存在 QBParseInfo 对象的 nameToDest 属性中
  5. TOK_SELECT => 分别将查询表达式的语法部分保存在 destToSelExpr、destToAggregationExprs、destToDistinctFuncExprs 三个属性中
  6. TOK_WHERE => 将 where 部分的语法保存在 QBParseInfo 对象的 destToWhereExpr 属性中

第三阶段:逻辑操作符 Operator

Hive 最终生成的 MapReduce 任务,Map 阶段和 Reduce 阶段均由 OperatorTree 组成。逻辑操作符,就是在 Map 阶段或者 Reduce 阶段完成单一特定的操作。

基本操作符包括:TableScanOperator、SelectOperator、FilterOperator、JoinOperator、GroupByOperator、ReduceSinkOperator

由于Join、GroupBy、OrderBy 均需要在 Reduce 阶段完成,所以在生成相应操作的 Operator 之前都会先生成一个 ReduceSinkOperator,将字段组合并序列化为 Reduce Key/value,Partition Key

第四阶段:逻辑层优化器

大部分逻辑层优化器通过变换 OperatorTree,合并操作符,达到减少MapReduce Job,减少 shuffle 数据量的目的。

名称作用
② SimpleFetchOptimizer优化没有 GroupBy 表达式的聚合查询
② MapJoinProcessorMapJoin 需要 SQL 中提供 hint,0.11 版本已不用
② BucketMapJoinOptimizerBucketMapJoin
② GroupByOptimizerMap 端聚合
① ReduceSinkDeDuplication合并线性的 OperatorTree 中 partition/sort key 相同的 Reduce
① PredicatePushDown谓词前置、谓词下推
① CorrelationOptimizer利用查询中的相关性,合并有相关性的 Job,Hive-2206
② ColumnPruner字段剪枝

表格中 ① 的优化器军事一个 Job 干尽可能多的事情/合并。② 的都是减少 shuffle 数据量,设置不做 Reduce。

PredicatePushDown 优化器:

image-20211101152515470

SQL 示例:谓词下推有些动作能限制性的话就尽量先执行。

select a.*,b.* from a join b on a.id = b.id where b.id > 18;

select a.*,c.* from a join (select b.* from b where b.id > 18) c on a.id = c.id

第五阶段:OperatorTree 生成 MapReduce Job 过程

OperatorTree 转化为 MapReduce Job 的过程分为一起阶段:

  1. 对输出表生成 MoveTask
  2. 从 OperatorTree 的其中一个根节点向下深度优先遍历
  3. ReduceSinkOperator 标示 Map/Reduce 的界限,多个 Job 间的界限
  4. 遍历其他根节点,碰到 JoinOperator 合并 MapReduceTask
  5. 生成 StatTask 更新元数据
  6. 剪断 Map 与 Reduce 间的 Operator 的关系

第六阶段:物理层优化器

MapJoin 优化器原理

名称作用
VectorizerHIVEHIVE - 4160,在0.13中发布
SortMergeJoinResolver与 bucket 配合,类似于归并排序
SamplingOptimizer并行 order by 优化器,在 0.12中发布
CommonJoinResolver + MapJoinResolverMapJoin 优化器
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值