在 Apache Hive 中,一条 SQL 查询(HiveQL)的执行会经过多个步骤,涉及编译、优化、资源分配和分布式执行。以下是详细流程(以 MapReduce 引擎为例,Tez/Spark 引擎类似但更高效):
1. 解析与编译(Parse & Compile)
- SQL 解析:
使用 ANTLR 解析器将 SQL 字符串转换为抽象语法树(AST),验证语法正确性。 - 语义分析:
检查表/列是否存在、数据类型匹配、权限验证等。 - 生成逻辑计划(Logical Plan):
将 AST 转换为逻辑操作树(如SELECT、JOIN、GROUP BY等算子)。
2. 逻辑优化(Logical Optimization)
Hive 应用规则优化逻辑计划:
- 谓词下推(Predicate Pushdown):
提前执行过滤(如WHERE条件),减少数据处理量。 - 列剪裁(Column Pruning):
仅读取查询涉及的列,忽略无关列。 - 分区剪裁(Partition Pruning):
若表有分区,只扫描相关分区目录(如WHERE dt='2023-01-01')。 - MapJoin 优化:
小表自动转为 Map 端 Join,避免 Shuffle。
3. 生成物理计划(Physical Plan)
将逻辑计划转换为可执行任务(如 MapReduce 作业):
- 切分 Stage:
根据依赖关系将任务拆分为 MapStage 和 ReduceStage(例如GROUP BY需要 Reduce)。 - 序列化计划:
生成 XML 格式的plan.xml,描述任务细节(输入路径、算子、输出等)。
4. 优化物理计划(Physical Optimization)
- 合并操作符:
如将多个SELECT投影合并为一个 Map 任务。 - 推测执行(Speculative Execution):
为慢任务启动备份副本。 - 动态分区优化:
处理INSERT INTO ... PARTITION的分区写入。
5. 执行引擎提交
- 资源申请:
Hive 客户端向 YARN ResourceManager 提交作业,申请资源。 - 生成 DAG:
引擎(MapReduce/Tez/Spark)将物理计划转为有向无环图(DAG)。
6. 分布式执行(以 MapReduce 为例)
▶ Map 阶段(Mapper)
- 输入:读取 HDFS 数据(如文本/ORC/Parquet 文件)。
- 处理:
执行投影(SELECT列)、过滤(WHERE)、部分聚合(如GROUP BY的局部合并)。 - 输出:生成
<Key, Value>对并分区(Partitioning)排序(Sorting)。
▶ Shuffle 阶段
- 数据传输:
将 Map 输出的 Key 按 Hash 分发到对应 Reduce 节点。 - 排序合并:
Reduce 端接收数据并按 Key 排序(Sort-Merge)。
▶ Reduce 阶段(Reducer)
- 聚合/连接:
执行最终聚合(SUM/AVG)、JOIN、ORDER BY等操作。 - 输出:结果写入 HDFS 临时目录。
7. 结果收集与返回
- Fetch 阶段:
客户端从 HDFS 读取最终结果(如LIMIT 100只取部分数据)。 - 输出方式:
返回控制台 / 写入 Hive 表 / 导出到 HDFS 目录。
8. 清理(Cleanup)
- 删除临时中间文件(依赖
hive.cleanup.scripts.on.failure配置)。 - 释放 YARN 容器资源。
关键优化技术
- 引擎选择:
- MapReduce:稳定但慢(默认)
- Tez:DAG 优化,减少中间落盘(推荐)
- Spark:内存计算,迭代计算高效
- 向量化(Vectorization):
一次处理一批数据(ORC/Parquet 格式支持)。 - 成本优化器(CBO):
使用hive.cbo.enable=true基于统计信息(行数/NDV)优化 Join 顺序。
示例:SELECT dept, AVG(salary) FROM emp GROUP BY dept
- Map:
读取emp表,输出<dept, salary>。 - Shuffle:
按dept分组发送到 Reducer。 - Reduce:
计算每个dept的平均工资,输出到 HDFS。 - Fetch:
客户端返回结果到控制台。
通过理解执行流程,可针对性优化 SQL(如避免全表扫描、利用分区表、小表 MapJoin 等)。实际日志可通过 EXPLAIN [EXTENDED] SQL 查看详细计划。
1154

被折叠的 条评论
为什么被折叠?



