看懂Hive的执行计划

官方文档
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Explain

关于Hive执行计划简述

一般执行计划有两个部分:
stage dependencies 各个stage之间的依赖性
stage plan 各个stage的执行计划

一个stage并不一定是一个MR,有可能是Fetch Operator,也有可能是Move Operator。

一个MR的执行计划分为两个部分:
Map Operator Tree MAP端的执行计划
Reduce Operator Tree Reduce端的执行计划

一些常见的Operator:
TableScan 读取数据,常见的属性 alias

Select Operator 选取操作
Group By Operator 分组聚合, 常见的属性 aggregations、mode , 当没有keys属性时只有一个分组。
Reduce Output Operator 输出结果给Reduce , 常见的属性 sort order
Fetch Operator 客户端获取数据 , 常见属性 limit

常见的属性的取值及含义:
aggregations 用在Group By Operator中
count()计数

mode 用在Group By Operator中
hash 待定
mergepartial 合并部分聚合结果
final

sort order 用于Reduce Output Operator中
+ 正序排序
不排序
++按两列正序排序,如果有两列
+- 正反排序,如果有两列
-反向排序
如此类推

下面是一些典型的操作的执行计划

先看一个简单的执行计划

hive> explain select count(*) from t_data1 ;

STAGE DEPENDENCIES:
  Stage-1 is a root stage
  Stage-0 depends on stages: Stage-1
#说明stage之间的依赖性

STAGE PLANS:  #各个stage的执行计划
  Stage: Stage-1
    Map Reduce  #这个stage是一个MR
      Map Operator Tree:  #Map阶段的操作树
          TableScan  #扫描表,获取数据
            alias: t_data1  扫描的表别名
            Statistics: Num rows: 1 Data size: 43835224 Basic stats: COMPLETE Column stats: COMPLETE
            Select Operator  #选取操作
              Statistics: Num rows: 1 Data size: 43835224 Basic stats: COMPLETE Column stats: COMPLETE
              Group By Operator   #分组聚合操作,不指定Key,只有一个分组
                aggregations: count()  聚合操作
                mode: hash    模式?    
                outputColumnNames: _col0  输出列名
                Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: COMPLETE
                Reduce Output Operator   #输出结果给Reduce
                  sort order:         #不排序
                  Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: COMPLETE
                  value expressions: _col0 (type: bigint)   #value表达式
      Reduce Operator Tree:   #Reduce的操作树
        Group By Operator    #分组聚合操作
          aggregations: count(VALUE._col0)   聚合操作
          mode: mergepartial      合并各个map所贡献的各部分
          outputColumnNames: _col0
          Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: COMPLETE
          File Output Operator   #文件输出操作
            compressed: false    不压缩
            Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: COMPLETE
            table:
                input format: org.apache.hadoop.mapred.TextInputFormat
                output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
                serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe

  Stage: Stage-0   #依赖于Stage1的stage0
    Fetch Operator  #获取数据操作
      limit: -1     #不限定
      Processor Tree:  
        ListSink

这是一个简单的count(*)的执行计划

再来看一个count(distinct)的执行计划

hive> explain select count(distinct sid) from t_data1 ;

STAGE DEPENDENCIES:
  Stage-1 is a root stage
  Stage-0 depends on stages: Stage-1

STAGE PLANS:
  Stage: Stage-1
    Map Reduce
      Map Operator Tree:
          TableScan
            alias: t_data1
            Statistics: Num rows: 5479403 Data size: 43835224 Basic stats: COMPLETE Column stats: NONE
            Select Operator
              expressions: sid (type: bigint)  #选取SID
              outputColumnNames: sid
              Statistics: Num rows: 5479403 Data size: 43835224 Basic stats: COMPLETE Column stats: NONE
              Group By Operator   #分组聚合操作
                aggregations: count(DISTINCT sid)  #聚合算子
                keys: sid (type: bigint)   #分组键
                mode: hash
                outputColumnNames: _col0, _col1
                Statistics: Num rows: 5479403 Data size: 43835224 Basic stats: COMPLETE Column stats: NONE
                Reduce Output Operator  #输出到Reduce
                  key expressions: _col0 (type: bigint)  #键表达式
                  sort order: +     #正向排序
                  Statistics: Num rows: 5479403 Data size: 43835224 Basic stats: COMPLETE Column stats: NONE
      Reduce Operator Tree:  
        Group By Operator   #分组聚合操作
          aggregations: count(DISTINCT KEY._col0:0._col0)
          mode: mergepartial   #合并各个部分聚合结果
          outputColumnNames: _col0
          Statistics: Num rows: 1 Data size: 16 Basic stats: COMPLETE Column stats: NONE
          File Output Operator
            compressed: false
            Statistics: Num rows: 1 Data size: 16 Basic stats: COMPLETE Column stats: NONE
            table:
                input format: org.apache.hadoop.mapred.TextInputFormat
                output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
                serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe

  Stage: Stage-0
    Fetch Operator
      limit: -1
      Processor Tree:
        ListSink

分组聚合的例子

explain select applove_date , count(*) from t_data1 group by applove_date ;

STAGE DEPENDENCIES:
  Stage-1 is a root stage
  Stage-0 depends on stages: Stage-1

STAGE PLANS:
  Stage: Stage-1
    Map Reduce
      Map Operator Tree:
          TableScan
            alias: t_data1
            Statistics: Num rows: 1095880 Data size: 43835224 Basic stats: COMPLETE Column stats: NONE
            Select Operator
              expressions: applove_date (type: timestamp)
           
<think> 我们正在讨论如何理解Hive中的EXPLAIN输出。根据引用内容,EXPLAIN是理解Hive如何将查询转换为MapReduce任务的关键工具。我们需要逐步解析EXPLAIN的输出,以便化查询性能。 EXPLAIN的输出包含多个部分,每个部分都描述了查询执行计划的不同方面。主要部分包括: 1. 抽象语法树(Abstract Syntax Tree, AST):Hive使用Antlr解析器将SQL转化为AST。 2. 阶段依赖图(Stage Dependencies):显示各个阶段的依赖关系。 3. 阶段计划(Stage Plans):每个阶段的详细执行计划,包括操作符树。 现在,我们详细解释EXPLAIN的输出: ### 1. 抽象语法树(AST) 在Hive中,使用`EXPLAIN EXTENDED`可以查看更详细的信息,包括AST。例如: ```sql EXPLAIN EXTENDED SELECT SUM(id) FROM my; ``` 输出中的`ABSTRACT SYNTAX TREE`部分展示了查询的语法树结构。每个节点以`TOK_`开头,表示不同的语法单元。例如: - `TOK_QUERY`:表示整个查询。 - `TOK_FROM`:表示FROM子句。 - `TOK_TABREF`:表示表引用。 - `TOK_INSERT`:表示插入操作(Hive将所有查询视为插入到某个目标,如临时文件)。 - `TOK_SELECT`:表示SELECT子句。 - `TOK_SELEXPR`:表示选择表达式。 - `TOK_FUNCTION`:表示函数用。 AST帮助我们理解Hive如何解析SQL语句,但在化和执行计划中,我们更关注后续部分。 ### 2. 阶段依赖图(Stage Dependencies) 这部分描述了执行计划中各个阶段的依赖关系。例如: ``` STAGE DEPENDENCIES: Stage-1 is a root stage Stage-0 depends on stages: Stage-1 ``` 这表示Stage-1是根阶段(即最先执行),Stage-0依赖于Stage-1(即Stage-1执行完后执行Stage-0)。 ### 3. 阶段计划(Stage Plans) 每个阶段都有一个详细的计划,描述了该阶段的操作。例如: ``` STAGE PLANS: Stage: Stage-1 Map Reduce Map Operator Tree: TableScan alias: my Statistics: Num rows: 100 Data size: 1000 Basic stats: COMPLETE Column stats: NONE Select Operator expressions: id (type: int) outputColumnNames: id Group By Operator aggregations: sum(id) mode: hash ... Reduce Operator Tree: Group By Operator aggregations: sum(VALUE._col0) ... ``` - **TableScan**:扫描表,读取数据。 - **Select Operator**:选择列,可能进行一些过滤或转换。 - **Group By Operator**:进行聚合操作。在Map阶段可能是部分聚合(`mode: hash`),在Reduce阶段进行最终聚合。 - **Reduce Operator Tree**:Reduce阶段的操作,通常处理来自多个Map任务的输出。 ### 关键操作符解析 - **TableScan**:扫描表,显示表别名和统计信息(如行数、数据大小等)。 - **Select Operator**:投影操作,选择需要的列,并可能进行表达式计算。 - **Filter Operator**:过滤操作,根据条件过滤行。 - **Group By Operator**:聚合操作,如果包含聚合函数(如SUM)。 - **Reduce Output Operator**:Map任务的输出,包括键和值,用于Reduce阶段。 - **File Output Operator**:将结果写入文件。 ### 如何化 通过EXPLAIN的输出,我们可以识别潜在的性能问题: - **数据倾斜**:如果某个Reduce任务处理的数据远多于其他任务,可能需要在Group By之前添加随机前缀进行分发。 - **全表扫描**:若没有使用分区或索引,导致扫描整个表,应考虑添加过滤条件或使用分区。 - **不必要的Shuffle**:如果阶段之间数据传输量大,考虑化JOIN或聚合操作。 ### 示例分析 引用[4]中提到,两个不同的SQL语句(如使用不同表别名)可能生成相同的执行计划,说明Hive会自动化[^4]。因此,通过EXPLAIN可以验证化器是否按预期工作。 ### 总结步骤 1. 使用`EXPLAIN [EXTENDED]`命令查看查询计划。 2. 关注阶段依赖,确定执行顺序。 3. 分析每个阶段的Map和Reduce操作符树,了解具体操作。 4. 注意统计信息(如行数、数据大小),评估数据分布。 5. 根据执行计划化查询,如添加分区、避免全表扫描等。 §§ 相关问题 §§ 1. Hive中如何解读`EXPLAIN EXTENDED`的输出与普通`EXPLAIN`的区别? 2. 如何通过`EXPLAIN`的输出识别数据倾斜问题? 3. Hive执行计划中的统计信息(如Num rows)是如何计算和使用的? 4. 在Hive执行计划中,`Map Operator Tree`和`Reduce Operator Tree`分别代表什么? 5. 如何利用`EXPLAIN`Hive的JOIN操作? </think> ### 如何理解 Hive 中 EXPLAIN 的执行计划结果 Hive 的 `EXPLAIN` 命令是分析查询性能的核心工具,它能将 SQL 查询转化为可理解的执行计划。以下是解读执行计划的关键步骤和要素: --- #### 一、执行计划的核心结构 Hive 执行计划本质上是 **MapReduce 任务的逻辑表示**,主要包含三部分: 1. **抽象语法树 (AST)** Hive 首先将 SQL 解析成树状结构(TOK_前缀节点),展示查询的语法逻辑[^2]。 *示例:* ```sql (TOK_QUERY (TOK_FROM (TOK_TABREF my)) (TOK_SELECT (TOK_FUNCTION SUM (TOK_TABLE_OR_COL id))) ``` - `TOK_QUERY`:根节点表示整个查询 - `TOK_FROM`:数据来源 - `TOK_SELECT`:计算逻辑 2. **阶段依赖图 (Stage Dependencies)** 描述任务阶段的执行顺序和依赖关系[^1]: ``` Stage-1 (ROOT) Stage-2 (DEPENDS ON Stage-1) Stage-0 (DEPENDS ON Stage-2) ``` - `ROOT`:起始阶段 - `DEPENDS ON`:阶段依赖顺序 3. **操作符树 (Operator Tree)** 每个阶段的具体操作步骤,关键操作符: - **TableScan**:扫描表数据(显示表名和统计信息) - **FilterOperator**:WHERE 条件过滤 - **SelectOperator**:列投影(选择特定列) - **GroupByOperator**:GROUP BY 聚合 - **ReduceOutputOperator**:Shuffle 数据传输 - **FileOutputOperator**:结果输出 --- #### 二、关键解读技巧 1. **识别性能瓶颈** 关注耗时操作: - `TableScan` 显示全表扫描时需检查分区过滤 - 大表 `JOIN` 时出现 `ReduceOutputOperator` 可能需化 - `GroupByOperator` 的 `mode: hash` 更高效,`mode: mergepartial` 需二次聚合 2. **分析数据流** 通过操作符顺序理解数据处理流程: ```sql Map Operator Tree: # Map阶段 TableScan → FilterOperator → SelectOperator → GroupByOperator Reduce Operator Tree: # Reduce阶段 GroupByOperator → FileOutputOperator ``` - Map 阶段负责数据过滤和预处理 - Reduce 阶段处理聚合和最终输出 3. **验证化效果** 对比化前后的执行计划: - 化前:`FilterOperator` 在 `JOIN` 之后 → 低效 - 化后:`FilterOperator` 在 `JOIN` 之前 → 高效(谓词下推)[^4] 4. **关注统计信息** 关键元数据: ```sql TableScan alias: users Statistics: Num rows: 1,000,000 # 行数 Data size: 256 MB # 数据大小 Basic stats: COMPLETE # 统计信息完整性 ``` - 数据量过大时需考虑分区或分桶 - `Basic stats: NONE` 表示需执行 `ANALYZE TABLE` --- #### 三、实战案例分析 **查询:** ```sql EXPLAIN SELECT dept, AVG(salary) FROM employees WHERE age > 30 GROUP BY dept; ``` **执行计划解读:** ``` STAGE DEPENDENCIES: Stage-1: Map Reduce # 核心计算阶段 Stage-0: Fetch # 结果输出阶段 Stage-1 Map Operator Tree: TableScan(employees) FilterOperator(age > 30) → 先过滤数据 SelectOperator(dept, salary) → 投影所需列 GroupByOperator(keys: dept, aggrs: avg(salary)) Stage-1 Reduce Operator Tree: GroupByOperator(keys: dept, aggrs: avg(salary)) → 最终聚合 FileOutputOperator(format: Text) → 结果写入HDFS ``` - **化点**: - 谓词下推 (`FilterOperator` 在扫描后立即执行) ✔️ - 两阶段聚合(Map 端预聚合 + Reduce 端最终聚合)✔️ --- #### 四、高级使用技巧 1. **扩展模式** `EXPLAIN EXTENDED` 显示更详细逻辑(如 AST 和表达式类型)[^2]: ```sql EXPLAIN EXTENDED SELECT ... ``` 2. **化器验证** 检查 Cost-Based Optimizer (CBO) 决策: ```sql EXPLAIN CBO SELECT ... ``` 3. **资源分析** 结合 `EXPLAIN DEPENDENCY` 查看输入输出依赖: ```sql EXPLAIN DEPENDENCY SELECT ... ``` > **最佳实践**:定期使用 `EXPLAIN` 验证查询化效果,重点关注数据扫描量、Shuffle 数据量和聚合方式[^1][^3]。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值