2021SC@SDUSC
山大软工实践hive(5)-逻辑优化(1)
逻辑优化,顾名思义,就是通过调整语句的执行顺序,或者优化语句,减少时间、内存上的开销。许多思路与普通数据库的查询优化一样。根据这一阶段输入输出都是DAG,可以认为是用过调整DAG的结构达到目的。
几种方式
参考他人博客有以下几种方式
谓词下推
让选择运算优先执行,比如 select 1 from a join b on a.id=b.id where a.id=5 and b.id>10,会优先执行a.id=5与b.id>10,然后再进行join操作,因为join操作的时间复杂度是O(nlogn)的,选择运算为O(n),有理由减少JOIN的输入数据量。比如下图把过滤操作提前,让JOIN可以处理更少的数据,用更少的空间
常量折叠
在涉及常量的运算上简化 1.如果表达式全为常量,就可把结果先算出来替代表达式 2.and or运算的逻辑短路 3.表达式中的常量传递。如a=1,b=a,c=b,即可直接给b,c赋值为1
1,3和代码编译成汇编语言一个思路,把可以替代的替代了;2是在hql中的and or实现逻辑短路,是必须实现的
合并RS算子
DAG上同一路径上的符合条件的两个RS算子合并成一个 要同时满足排序,分组,升降序上,key元素组的包含关系(如a,b,c 包含a,b 不包含 a,d)然后 1.排序上合并为要求更精密的一个。比如算子分别以(a,b),(a)排序,则路径上前面的算子以(a,b)排序,后面的算子删除 2.分组上合并为要求更模糊的。比如以(a,b),(a)分组,则路径上前面的算子以(a)分组,后面的算子删除 3.排序顺序合并为要求更多的,比如按(a,b,c,升序,升序,降序),(a,b,升序,升序)合并为(a,b,c,升序,升序,降序)
同时还要满足两个RS算子的reducer数量相同,如果合并前其中有RS的reducer数量咋运行时决定那么合并后也得如此
join顺序优化
把大表放在join操作的最后面。hive把前面n-1张表读入内存,和最后一张表join
select优化
比如select *,就可以不要SEL算子,因为不需要投影 列裁剪,比如select a from table where c=1,在全过程中只有a,c列使用,那么在读取表时,就可以只读取这两列,减少空间上的开销 分区裁剪,比如select a from table where c=1,系统就可以只读取c=1所在的分区(这应该需要配合普通索引或者hash索引之类的实现)
全局与局部
如果所有数据都集中给一个reducer处理,会导致速率变慢,这时候要想办法把它分成多个reducer任务 1.sort by代替order by order by会按要求字段进行全局排序,就会导致map端所有数据都分配给一个reducer,而sort by就会视情况启动多个reducer 2.添加group by 在进行如count()时,也会把所有数据分配给一个reducer,而如果进行select count() from( select count(*) from t group by key),就可以把任务分配个多个reducer
这一部分感觉是用户在语法上的优化,不知道hive本身有没有自动实现
源码分析部分
在optimizer包里很有可能包含逻辑优化的类,比如Optimizer类
package org.apache.hadoop.hive.ql.optimizer;
import ...
public class Optimizer {
里面有个初始化方法 方法里面是很多if语句,在这里面看到了一些之前了解过的优化,比如Groupby,skew join优化。可以确认这个类与逻辑优化有关,通过已确认的问题(hiveConf)进行优化 其中transformtions 为Transform数组,Transform为抽象类,由不同的优化器继承 最后应该调用这个执行优化并更改查询计划
选择其中一个优化器PointLookupOptimizer查看 这个优化器会尝试把or谓语换成更高效的in字句,暂不知道原理 PartitionColumnsSeparator
另外尝试直接搜索LogicalOptimizer,找到的是LogicalPlanOptimizer,它在org.apache.pig.newplan.logical.optimizer里 这个apache.pig是一种类sql语言,但不是hql,所以不是需要分析的内容
下一步
继续从理论上与实现上双向包围
吐槽
一个学习前置技术的课程,要求从一些固定的选题中选择题目,分析源码,小组内看的代码不同。 这也太坑了,一是源码分析对学习技术帮助太小,不如找教程分析;二是小组内看的代码不能相同,我很希望他们试试看书从中间开始看,特别折磨人还看不懂,上百千个包与类,总共十万百万行的代码,层层嵌套。
参考
Hive逻辑优化 Hive优化总结
|