Hive执行计划JSON详解

我们来详细解析 Hive 执行计划的 JSON 格式。Hive 使用 Apache Calcite 作为优化器框架后,其执行计划(EXPLAIN FORMATTEDEXPLAIN)的输出变成了一个非常结构化、信息丰富的 JSON 对象。

这个 JSON 包含了从逻辑计划到物理计划的完整转换过程,是深入理解 Hive 如何执行查询的钥匙。

1. 如何获取 JSON 格式的执行计划?

在 Hive 中,使用 EXPLAIN 命令并指定 JSON 格式来获取。

EXPLAIN FORMATTED JSON
SELECT e.deptno, d.dname, AVG(e.sal) AS avg_sal
FROM emp e
JOIN dept d ON e.deptno = d.deptno
WHERE e.sal > 1000
GROUP BY e.deptno, d.dname
HAVING avg_sal > 2000;

或者使用较新版本的 EXPLAIN 直接输出(不同版本命令可能略有差异):

EXPLAIN JSON YOUR_QUERY;

2. JSON 执行计划的核心结构

执行计划的 JSON 输出是一个非常庞大的对象,但其核心结构可以分解为以下几个主要部分。一个典型的执行计划 JSON 可能包含多个“计划”版本(如逻辑计划、优化后的逻辑计划、物理计划等)。

{
  "version": "1.0",
  "sessionId": "...",
  "cpuTime": "...",
  "plan": { ... }, // 这是最核心的部分,描述了整个查询计划
  "optimizedPlan": { ... }, // 优化后的逻辑计划
  "physicalPlan": { ... }, // 最终的物理执行计划(通常是这个)
  "optimizer": "...",
  "tables": [ ... ], // 查询涉及的表信息
  "metadata": { ... }
}

我们最需要关注的是 "plan""optimizedPlan""physicalPlan" 这几个对象,它们都具有递归的树形结构。

3. 计划节点(Plan Node)的通用结构

每个计划节点(无论是逻辑的还是物理的)都遵循一个通用的模式:

{
  "nodeType": "HiveSortLimit", // 节点类型,非常重要!标识了这个节点的操作(如 Join, Filter, Project, TableScan 等)
  "input": [ ... ], // 一个数组,包含该节点的子节点(输入源)。叶子节点(如 TableScan)的 input 为空。
  "identifier": "...", // 标识符
  "props": { ... }, // 属性(Properties),包含该操作的具体信息,是分析的精华所在
  "rowType": { ... }, // 输出行的 schema(字段名和类型)
  "cost": { ... }, // 优化器估算的成本信息
  "hints": [ ... ],
  "relatedNodes": [ ... ]
}

4. 详解关键节点类型及其 props

这是理解执行计划的核心。不同的 nodeType 有不同的 props

a. HiveTableScan

作用: 从表中扫描数据。
props 关键字段

  • table: 表名(如 [db_name, table_name])。
  • columns: 查询所涉及的列。
  • filterPredicate: 非常重要!如果查询有分区过滤(WHERE dt='2023-10-01')或字段过滤,会在这里体现。这是判断分区剪枝是否生效的关键。
  • selectedPartitions: 实际扫描的分区列表和数量,结合 filterPredicate 可以确认分区剪枝效果。

示例

{
  "nodeType": "HiveTableScan",
  "props": {
    "table": "[default, emp]",
    "columns": ["deptno", "sal"],
    "filterPredicate": "($1 > 1000)" // 对应 WHERE sal > 1000
  },
  "input": []
}
b. HiveFilter

作用: 执行 WHERE 子句中的过滤条件。
props 关键字段

  • condition: 过滤条件的详细 SQL 表达式。

示例

{
  "nodeType": "HiveFilter",
  "props": {
    "condition": "($1 > 1000)" // 过滤条件
  },
  "input": [ ... ] // 它的输入通常是 TableScan 或其他节点
}
c. HiveProject

作用: 执行 SELECT 子句中的列选择、计算和别名。
props 关键字段

  • expressions: 投影的表达式列表(例如 $0, $1, $0 + $1, AS alias)。

示例

{
  "nodeType": "HiveProject",
  "props": {
    "expressions": ["$0", "$1", "($1 + 100) AS increased_sal"]
  },
  "input": [ ... ]
}
d. HiveAggregate

作用: 执行 GROUP BY 和聚合函数(如 SUM, AVG, COUNT)。
props 关键字段

  • group: GROUP BY 的分组字段(索引)。
  • aggs: 聚合函数的列表和详细信息。
  • mode: 聚合模式,如 PARTIAL1, FINAL。这在 MapReduce 或 Tez 中很常见,表示这是局部聚合还是最终聚合。

示例

{
  "nodeType": "HiveAggregate",
  "props": {
    "group": [0], // 按第一个字段分组
    "aggs": [["AVG", false, [$1], null]], // 对第二个字段求平均值
    "mode": "PARTIAL1"
  },
  "input": [ ... ]
}
e. HiveJoin

作用: 执行表连接(JOIN)。
props 关键字段

  • condition: 连接条件(如 =($0, $3))。
  • joinType: 连接类型,如 INNER, LEFT, RIGHT, FULL
  • algorithm: 极其重要!Hive 选择的连接算法。
    • CommonJoin / ShuffleJoin: 洗牌连接(Reduce 端连接)。
    • MapJoin: Map 端连接(通常用于小表)。
    • BucketJoin: 分桶表连接。
    • SMBJoin: 排序分桶连接。
  • leftKeys, rightKeys: 左右表用于连接的键。

示例

{
  "nodeType": "HiveJoin",
  "props": {
    "condition": "=($0, $3)",
    "joinType": "INNER",
    "algorithm": "MapJoin", // 看到这个通常表示性能较好
    "leftKeys": [0],
    "rightKeys": [0]
  },
  "input": [ leftChildPlan, rightChildPlan ]
}
f. HiveSortLimit

作用: 执行 ORDER BYLIMIT
props 关键字段

  • collation: 排序字段和顺序(如 $0 DESC)。
  • fetch: LIMIT 的数量。
  • offset: OFFSET 的数量。

5. 如何阅读和分析 JSON 执行计划?

  1. 自底向上阅读: 从最内层的 input 开始,通常是 HiveTableScan 节点,然后逐步向外看它们是如何被 Filter, Project, Join 等操作处理的。
  2. 关注关键 nodeType: 快速定位 HiveJoin(看算法)、HiveTableScan(看过滤)、HiveAggregate(看分组)。
  3. 深入研究 props
    • HiveTableScan: 检查 filterPredicateselectedPartitions 确认分区/分区剪枝是否生效。
    • HiveJoin: 检查 algorithm。如果是 CommonJoin,思考能否优化为 MapJoin(如确保小表)。
  4. 注意 mode: 在 HiveAggregate 中,PARTIALFINAL 模式意味着可能有多个 MR/Tez 阶段。
  5. 查看 rowType: 可以帮助你跟踪每个操作步骤后,数据列的形态变化。
  6. 使用可视化工具(推荐): 手动解析庞大的 JSON 非常困难。可以将 JSON 复制到一些在线可视化工具中(例如 https://czharry.github.io/learnhive/),它们能将 JSON 转换成树形图,使得整个执行流程一目了然。

总结

Hive 的 JSON 执行计划提供了无与伦比的细节深度,是进行高级 SQL 调优的必备技能。通过理解其核心结构和关键节点的属性,你可以:

  • 确认优化是否生效: 如分区剪枝、谓词下推。
  • 识别性能瓶颈: 如大表触发了 CommonJoin 而不是 MapJoin
  • 理解查询的执行流程: 清楚地看到数据是如何一步步被处理和转换的。

虽然一开始会感到复杂,但通过练习和借助可视化工具,你会逐渐掌握这项强大的调优能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值