当前位置: 首页 > news >正文

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%。

http://www.xdnf.cn/news/380269.html

相关文章:

  • 使用 Jackson 在 Java 中解析和生成 JSON
  • Spring事务管理实现机制
  • Windows右键管理工具:轻松添加/删除/修改右键菜单项!
  • xml与注解的区别
  • 机器学习 day01
  • 如何更改typora图片存储位置
  • 将一张100 元的钞票换成1 元、2元、5 元和10 元的零钱,每种零钞至少一张
  • CH579 CH573 CH582 CH592 蓝牙主机(Central)实例应用讲解
  • C. scanf 函数基础
  • Linux--JsonCpp
  • 【C++】内存管理
  • Lettuce 节点刷新、连接优化与 Spring 升级适配全解析:从环境约束到生产验证
  • printf调试时候正常,运行时打印不出来
  • spring响应式编程系列:异步消费数据
  • springboot3+vue3融合项目实战-大事件文章管理系统-更新用户信息
  • MGP-STR:用于场景文本识别的多粒度预测
  • 【Vulkan 入门系列】创建和配置描述符集,创建同步对象(九)
  • 跟我学C++中级篇——STL中的删除对比
  • C++ learning day 02
  • 常见的算法介绍
  • 人脸真假检测:SVM 与 ResNet18 的实战对比
  • Java单例模式总结
  • 【Linux 系统调试】系统内存越界调试利器Electric Fence详解
  • waterfall与Bidding的请求机制
  • Day20打卡-奇异值SVD分解
  • Python序列化的学习笔记
  • 基于PE环境搭建及调试S32K312
  • Lua—元表(Metatable)
  • 怎样使自己处于高能量状态
  • Discriminative and domain invariant subspace alignment for visual tasks