AST(抽象语法树)与 HBO(基于历史的优化)详解

在 Hive SQL 优化中,AST(抽象语法树)HBO(基于历史的优化) 是两种高级优化手段,能够显著提升复杂查询的执行效率。以下是它们的核心原理、应用场景及具体示例:


一、AST(Abstract Syntax Tree,抽象语法树)

1. 什么是 AST?
  • 定义:AST 是 SQL 语句的树形结构表示,由 Hive 解析器生成,反映查询的语法逻辑(如 SELECT、JOIN、WHERE 等操作的嵌套关系)。

  • 作用:Hive 优化器通过遍历和修改 AST,重构查询逻辑,生成更高效的计算路径。

2. AST 优化示例

假设原始 SQL 如下:

SELECT * 
FROM (
  SELECT user_id, SUM(amount) AS total 
  FROM orders 
  GROUP BY user_id
) t 
WHERE total > 1000;
  • 原始 AST

    Project (输出字段)
    └─ Filter (total > 1000)
       └─ SubQueryAlias (t)
          └─ Aggregate (GROUP BY user_id)
             └─ TableScan (orders)

  • 优化后 AST(谓词下推):

    Project (输出字段)
    └─ Aggregate (GROUP BY user_id + HAVING total > 1000)
       └─ TableScan (orders)

    优化效果:将过滤条件 total > 1000 从外层下推到聚合操作中,减少中间数据传输。

3. 常见 AST 优化手段
  • 谓词下推(Predicate Pushdown):将 WHERE 条件提前到数据扫描阶段。

  • 常量折叠(Constant Folding):提前计算常量表达式(如 WHERE age > 30+2 优化为 age > 32)。

  • 子查询扁平化:将多层子查询合并为单层操作(如将嵌套 SELECT 转为 JOIN)。


二、HBO(History-Based Optimization,基于历史的优化)

1. 什么是 HBO?
  • 定义:HBO 通过收集历史执行数据(如统计信息、执行计划性能)动态优化后续查询,属于 基于成本的优化(CBO) 的扩展。

  • 核心依赖

    • 统计信息表大小、列基数(Cardinality)、数据分布(Histogram)等。

    • 执行历史历史任务的资源消耗、Shuffle 数据量、执行时长等。

2. HBO 优化流程
  1. 统计信息收集

    -- 收集表级统计信息(行数、文件大小)
    ANALYZE TABLE orders COMPUTE STATISTICS;
    ​
    -- 收集列级统计信息(最大值、最小值、基数)
    ANALYZE TABLE orders COMPUTE STATISTICS FOR COLUMNS user_id, amount;
  2. 优化器决策

    • 根据统计信息选择最优 JOIN 顺序(小表优先)。

    • 自动选择 Map Join 或 Reduce Join。

  3. 动态调优

    • 根据历史任务的倾斜情况,自动添加随机前缀解决数据倾斜。

3. HBO 应用示例

场景:两表 JOIN(orders 大表,users 小表)。

  • 无 HBO:默认使用 Reduce Join,引发大量 Shuffle。

  • 启用 HBO

    • 统计信息显示 users 表仅 10MB,触发 Map Join

    • 直接将小表广播到所有 Mapper,避免 Shuffle。

    -- 启用自动 Map Join
    SET hive.auto.convert.join=true;
    SET hive.mapjoin.smalltable.filesize=25000000; -- 小表阈值设为25MB
4. HBO 与 CBO 的关系
  • CBO(Cost-Based Optimization):基于统计信息估算执行计划成本(如 CPU、I/O、网络开销),选择最优方案。

  • HBO:在 CBO 基础上,进一步结合历史执行数据(如实际资源消耗)进行动态调整,属于 CBO 的增强版。


三、AST 与 HBO 的综合优化案例

问题 SQL
SELECT a.user_id, a.total 
FROM (
  SELECT user_id, SUM(amount) AS total 
  FROM orders 
  GROUP BY user_id
) a 
JOIN (
  SELECT user_id, SUM(amount) AS total 
  FROM orders 
  GROUP BY user_id
) b ON a.user_id = b.user_id 
WHERE a.total > 1000;
优化步骤
  1. AST 分析

    • 识别到两个相同的子查询 ab

    • 优化器将子查询合并为 公共表达式(CTE)

    WITH order_summary AS (
      SELECT user_id, SUM(amount) AS total 
      FROM orders 
      GROUP BY user_id
    )
    SELECT a.user_id, a.total 
    FROM order_summary a 
    JOIN order_summary b ON a.user_id = b.user_id 
    WHERE a.total > 1000;
  2. HBO 调优

    • 统计信息显示 orders 表的 user_id 基数较高(10万+),且 total 列存在倾斜。

    • 优化器自动为 GROUP BY user_id 添加 DISTRIBUTE BY 分桶,避免 Reducer 长尾。

    SET hive.groupby.skewindata=true; -- 自动处理倾斜

四、总结

优化技术核心原理典型场景
AST重构查询逻辑,减少计算层级和数据传输量多层嵌套子查询、冗余条件过滤
HBO基于统计信息和历史执行数据动态优化执行计划JOIN 顺序选择、数据倾斜自动处理

最终效果

  • 通过 AST 优化,查询执行计划的 Operator 数量减少 40%;

  • 通过 HBO 自动选择 Map Join,Shuffle 数据量降低 90%。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值