Hive SQL 语义分析:select count(*) from tableName

发布时间:2016-12-6 22:22:48 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"Hive SQL 语义分析:select count(*) from tableName",主要涉及到Hive SQL 语义分析:select count(*) from tableName方面的内容,对于Hive SQL 语义分析:select count(*) from tableName感兴趣的同学可以参考一下。

从客户端提交一个 Hive SQL  到 Driver 提交 MapReduce Job,有一个对SQL进行词法分析和语义分析的过程,下面以 select count(*) from tableName 来描述其过程。 一、词法分析 使用ANTLR分析SQL,生成语法树,每个节点是一个 ASTNode,它有自己的类型。 来看看 select count(*) from tableName 的语法树: ( TOK_QUERY ( TOK_FROM ( TOK_TABREF ( TOK_TABNAME tt2 ) ) ) ( TOK_INSERT ( TOK_DESTINATION ( TOK_DIR TOK_TMP_FILE ) ) ( TOK_SELECT ( TOK_SELEXPR ( TOK_FUNCTIONSTAR count ) ) ) ) ) 上面语法树中,除括号外,每行对应一个 ASTNode,共13个节点,相互构成父子关系。 如:TOK_QUERY和TOK_INSERT为TOK_FROM的子节点;tt2为TOK_TABNAME的子节点。 二、语义分析 首先根据SQL类型创建对应的SemanticAnalyzer,对于这个sql,创建的就是 SemanticAnalyzer 1.分析语法树的每个节点,将后面要用到的相关数据保存到 Query Block  2.查询表的元数据信息,顺便做些检查,如检查 table 是否 offline 3.创建 Operator 4.优化 5.生成 Task 这些步骤中,除去辅助工作外,最重要的是3、5部分。 3 根据语法树创建Operator 生成的 Operator 是个 DAG,每个节点是一个 Operator,每个 Operator 应该有指向所有子 Operator的指针,那么Operator的数据结构至少是这个样子: class Operator<T extends OperatorDesc> implements Node { public List<Operator<? extends OperatorDesc>> getParentOperators() { return parentOperators; } public List<Operator<? extends OperatorDesc>> getChildOperators() { return childOperators; } }先看看 select count(*) from tableName 的Operator:   为了生成  operator tree,首先创建 operator tree 的 root operator,而root operator 总是 TableScanOperator 这个步骤会为所有from字句中的表创建一个 TableScanOperator,将 TableScanOperator 和表名的对应关系保存起来。 最先创建的总是 TableScanOperator,以后每创建一个Operator 都将当前Operator作为它的父Operator ReduceSinkOperator和它的子Operator: GroupByOperator是同时创建的,它来帮助mapper输出结果,接着就由Reduce进行聚集操作。 所以创建Task时,如遇到处理的节点为ReduceSinkOperator,就直接根据它的子Operator 来生成Reduce Task. 可见这个SQL 中 TableScanOperator 的子Operator 只有一个 SelectOperator;FileSinkOperator  有一个父Operator: SelectOperator 在explain 中就可查看有哪些Operator: STAGE DEPENDENCIES:   Stage-1 is a root stage   Stage-0 is a root stage STAGE PLANS:   Stage: Stage-1     Map Reduce       Alias -> Map Operator Tree:         tt2            TableScan //[1]             alias: tt2             Select Operator //[2]               Group By Operator //[3]                 aggregations:                       expr: count()                 bucketGroup: false                 mode: hash                 outputColumnNames: _col0                 Reduce Output Operator //[4]                   sort order:                    tag: -1                   value expressions:                         expr: _col0                         type: bigint       Reduce Operator Tree:         Group By Operator //[5]           aggregations:                 expr: count(VALUE._col0)           bucketGroup: false           mode: mergepartial           outputColumnNames: _col0           Select Operator //[6]             expressions:                   expr: _col0                   type: bigint             outputColumnNames: _col0             File Output Operator //[7]               compressed: false               GlobalTableId: 0               table:                   input format: org.apache.hadoop.mapred.TextInputFormat                   output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat   Stage: Stage-0     Fetch Operator       limit: -1 上面 explain 中的Operator 已标出。 TableScanOperator 不用说了,望文生义吧 SelectOperator 可进行列修剪,可减少 mapper  的输出数据量。 GroupByOperator 进行聚集操作,map 端的自然只能做部分聚集了。 FileSinkOperator 向文件系统写SQL结果文件。 5根据 Operator tree 创建 Task 首先创建一个Dispatcher,它保存了用RegExp标识的规则和相应的节点处理器NodeProcessor的映射集合, 这个集合决定了每一个节点 Operator的命运,它决定了处理它的NodeProcessor. 不同的规则的正则表达式可匹配对应的 Operator。 然后顶端(TableScanOperator)开始遍历这个DAG,为每个节点(Operator)找出一个规则 Rule。 TableScanOperator 最匹配的规则对应的 NodeProcessor 是 GenMRTableScan1,它会创建一个 MapRedTask SelectOperator 找到的 Processor 为 GenMROperator,这个 Processor 仅仅保存了一下SelectOperator 和对应的 GenMRProcContext$GenMapRedCtx 的映射关系 ReduceSinkOperator 对应的 NodeProcessor: GenMRRedSink1 上面说过,以创建Task时,如遇到处理的节点为ReduceSinkOperator,就直接根据它的子Operator 来生成Reduce Task,这就是 GenMRRedSink1 来完成的。 具体来说,GenMRRedSink1 将这个 GroupByOperator 作为 reducer,把它存入当前任务中。当前任务就是刚才处理TableScanOperator时创建的 Task。 所有节点处理完后会生成所有的Task,此时 PhysicalOptimizer 会再优化一次。它遍历的其实还是个DAG,不过这时节点是 Task了。 至此,Task已经创建,可以着手创建Mapeduce Job 了。

上一篇:201309_The First Game[DP专题]
下一篇:整数溢出漏洞攻击

相关文章

相关评论