简单了解RBOCBO和HBO
RBO
基于规则的优化器(Rule-Based Optimizer)指的是不需要额外的信息,通过用户下发的SQL语句进行的优化,主要通过改写SQL,比如SQL子句的前后执行顺序等。比较常见的优化包括谓语下推、字段过滤下推、常量折叠、索引选择、Join优化等等。RBO对数据不敏感,在表大小固定的情况下,无论中间结果数据怎么变化,只要SQL保持不变,生成的执行计划就都是固定的。
CBO
基于代价的优化器(Cost-Based Optimizer)根据收集的统计信息来计算每种执行方式的代价,进而选择最优的执行方式。引入了重新排序Join(Join Reorder)和自动MapJoin(AutoMapJoin)优化规则等,同时基于Volcano模型的优化器会尽最大的搜索宽度来获取最优计划。可以设置规则白名单(使用哪些优化规则)、黑名单(关闭哪些优化规则)。
Optimizer 会提供谓词下推(PredicatePushDown)优化,主要目的是尽量早地进行谓词过滤,以减少后续操作的数据量,提高性能。但需要注意的是:
- UDF:对于UDF是否下推,优化器做了限制,不会任意下推这种带有用户意图的函数,主要是因为不同用户书写的函数含义不一样,不可以一概而论。
- 不确定函数:对于不确定函数,优化器也不会任意下推,比如sample函数,如果用户将其写在where子句中,同时语句存在Join,则优化器是不会下推到TableScan的。
- 隐式类型转换:书写SQL语句时,应尽量避免Join Key存在隐式类型转换。
CBO优化器通过给CPU、IO、NETWORK赋予代价,来指导生成更优的执行计划。

CBO组成
- Meta Manager:优化器在选择优化策略时会使用一些元数据,如数据表元数据,分区元数据,统计信息元数据等。
- Statistics:为优化器提供准确的统计信息,进行优化策略的选择。
- Rule Set:每一条优化规则都是特定场景下的优化点,优化器根据代价模型选择启用哪些规则。规则分为:
- Substitute Rule:优化了一定好的规则。
- Explore Rule:优化后需要考虑各种因素的规则。
- Build Rule:优化后不能再次优化的规则。
- Volcano Planner Core:把所有信息统一处理,根据代价模型,设计代价最小的方案。

代价计算
代价计算发生在产生的新节点注册阶段,计算规则如下:
- 如果代价不存在或者子节点的代价还没计算,则忽略。
- 如果有代价,则将本身的代价和子节点的代价相加,若小于目前的最优策略,则认为当前节点是最优的。还会对其父节点的代价进行迭代计算,进而估算整条链路的代价。
HBO
基于历史的优化器(History-Based Optimizer)在任务稳定的情况下,可以考虑基于任务的历史执行情况进行资源评估,即采用HBO。
- 提高CPU利用率。
- 提高内存利用率。
- 提高Instance并发数。
- 降低执行时长。
针对大促这类数据量暴涨的场景,HBO也增加了根据数据量动态调整Instance数的功能,主要依据Map的数据量增长情况进行调整。
HBO分配资源方法
- 核心思想:基础资源评估+加权资源评估。
- 基础资源评估:对于map任务的数量根据用户提交任务的数据量和每个map任务期望执行的数据量来估算;对于reduce任务个数由map任务的输入数据量估算或者根据近几天map任务对reduce任务的输出数据量的平均值进行估算。
- 加权资源评估:通过当前任务近期执行速度与任务预期执行速度作比较,如果小于预期则等比例添加资源,估算出最终的任务数量。

常见RBO优化点
- 各种表达式的重写和化简。
- Cast消除。
- 谓词化简。
- 公共谓词提取。
- 列裁剪。
- Shuffle列裁剪(确保任何多余的列不要参与网络传输)。
- 谓词下推。
- 等价谓词推导(常量传播)。
- Outer Join转Inner Join。
- Limit Merge。
- Limit下推。
- 聚合Merge。
- Intersect Reorder。
- 常量折叠。
- 公共表达式复用。
- 子查询改写。
- Lateral Join化简。
- Empty Node优化。
- Empty Union, Intersect, Except裁剪。
- In转Semi Join或者Inner Join。
- 聚合算子复用。
- Primary Key相关优化。
- 冗余Group By消除。
- Sum常量转Count。
- Data Skipping。
常见CBO优化点
- 多阶段聚合优化。
- Join左右表Reorder。
- Join多表Reorder。
- Join分布式执行选择。
- Shuffle Join。
- Broadcast Join。
- Bucket Shuffle Join。
- Colocate Join。
- Replication Join。
- Join和Aggregate Runtime Colocate, 避免Shuffle。
- CTE复用。
- CTE列裁剪。
- Agg上拉。
- Agg下推Join。
- Agg下推GroupingSets。
- 窗口下推Group By。
- 算子融合。
- 物化视图选择与改写。
- 利用基数信息进行优化。
HBO常见优化点
- 表元数据本地缓存(表来源、表定义、分区个数、分区信息、文件列表、统计信息等)。
- hdfs文件缓存。
- sql执行记录结果集落表(sql提交失败、运行失败、运行成功)。
- 保存历史sql执行时,预估内存值和实际消耗内存值。
- DataCache。
- 多表物化视图。

参考资料
end
