Hive的优化
1、Fetch的抓取
当set hive.fetch.task.conversion=none;简单查询会转化为Mapreduce程序,查询较慢
当set hive.fetch.task.conversion=more;简单查询不会转化为Mapreduce程序,查询较快
2、本地模式
计算任务在提交任务的节点上(本地)执行,不会提交到yarn
在少量数据的前提下,开启本地模式,Mapreduce任务不提交到Yarn,任务不提交到Yarn,任务的执行省去了Yarn的调度时间,可以加快查询效率
在少量数据的前提下,不开启本地模式,Mapreduce任务提交到Yarn,Yarn调度花费时间,任务执行时间较长
3、数据倾斜1
当数据倾斜时,使用Group by 对倾斜的字段进行分组,此时使用Map聚合可以加快查询效率
Map聚合会生成两个MapReduce任务,第一个MapReduce任务对数据进行随机分配,不按照分组的字段划分。第二个MapReduce任务,按照分组字段划分做最终的聚合。
注意:不是所有的计算都可以使用该方法,例如求平均数就不可以
4、Count(distinct)换成Count()+group by
企业中大量数据Count(distinct)效率较差,可以使用Count(id)+group by(id)替换
5、在join关联时,尽量不要出现笛卡尔积,即在join后必须加on条件。
6、使用分区剪裁,列剪裁
用哪个列,获取哪个列,多一个都不要获取
用哪个分区,就后去哪个分区,多一个都不要获取
7、Join和Where同时存在的优化
1、先join,后过滤,部分join的结果会被删除,造成无效join,这样效率较低。
2、先过滤后join,无效数据全部过滤掉,在join时留下的数据100%为有效数据,这样效率较高
8、动态分区的调整
以第一个表的分区规则,来对应第二个表的分区规则,讲第一个表的所有的分区,全部拷贝到第二个表中来,第二个表在加载数据的时候,不需要指定分区了,直接用第一个表的分区即可
执行步骤:
1、准备第一个表,分区,数据,创建第二个表(空表)
2、设置开启动态分区调整
3、在第一个表中讲分区查询出来写入第二个表
a)分区字段写在查询的最后。
9、数据倾斜2
调整Mao或Reduce的数量
查询一个文件数据插入到多个文件中,增加文件数量,从而增加Map数量,进一步增加数据查询的效率
set mapreduce.job.reduces=10;
create table a_1as;
select * from ori_partitiioned
distribute by rand();
10、Hive中影响Map数量的因素
文件数量
文件大小
数据块大小
注意:Map数量并不是越多越好
11、Hive中影响reduce数量的因素
方案一:数据总量/每个reduce处理的数据量
方案二:每个任务的最大reduce数量
Min(方案二,方案一)=N(reduce的值)
注意:reduce数量并不是越多越好
12、并行执行
Hive中会有很多阶段,如是MapReduce阶段,抽样阶段,合并阶段,Limit阶段,在各个阶段之间没有依赖,并相互之间没有影响的前提下,开启并行执行单位时间内计算的任务更多效率更高;
13、严格模式
Hive中不允许的高位动作
1、笛卡尔积 合法用法:必须加on条件
2、扫描所有分区 合法用法:必须指定分区字段
3、Orderby 后面不加limit 合法用法:必须加limit;
14、JVM重用
没有开启JVM宠用时,每个task需要单独篡改就JVM,使用完毕后在删除,当有很多task时,JVM会反复创建,删除,每个JVM的创建时间约1秒钟,反复创建浪费很多时间
开启JVM重用,首次创建一批JVM,这批JVM反复被使用,省去了反复创建JVM的过程,节省任务时间
弊端:在有任务执行比较慢的情况下,执行完的JVM不会自动释放资源,需所有任务结束后同i释放资源,释放之前,空前下来的资源,其他人不能使用,造成资源浪费
15、推测执行
当有部分任务区执行较慢,Hadoop会在集群中开启一个和原任务相同的任务,两个任务处理同一个数据,哪个任务先执行完,就以哪个任务的结果为准