Hive 如何优化查询速度?
最近刚好我在改Hive源码,对整体还算比较熟悉,说点真正运行Job的参数配置的,要提高查询速度的话,除了常见的做一些分区,这些架构层面的东西,运行态的参数也很重要。
写的时候把mergefiles打开:
SET hive.merge.mapfiles=true; |
这种情况下,写入速度会稍慢,但是查询速度会加快。
如果使用的对象存储,请使用对应的committer,不要使用自带的那个FileOutputCommitter.
SET hive.blobstore.supported.schemes=s3,s3a,s3n,xxx; |
Reduce是通过多线程,从Map端把数据拷贝过来的,默认是5,如果你的机器规格较高,可以调大这个并发度,另外如果Map 产生的数据较小的话,它会把这个内容先放在内存中,而内存是否鞥放下,也是由mapred.job.shuffle.input.buffer.percent去控制的,它的值是个百分比,堆内存的百分比,和Reduce端去拖数据相关的这一堆配置可用基于你的机器规格进行调整:
set mapred.reduce.parallel.copies=30; |
基本的Reduce和Map的内存,不解释了:
set mapreduce.map.memory.mb=4096; |
如果你使用了llap的话,可以调整一下llap的并行度:
set hive.llap.memory.oversubscription.max.executors.per.query=8; |
将Common Join转换成Map Join,在两个表大小不一样的时候,可以使用一下:
set hive.auto.convert.join.hashtable.max.entries=-1; |
如果你是分区表,那么可以使用一下这个参数,这个在查询过程中,有写临时表的情况下,会很有效果,这个的意思是说把你的数据sort后,同样的分区内容的数据,会归纳到同一个FlieSink来处理,可以极大的降低乱序带来的内存消耗:
set hive.optimize.sort.dynamic.partition=true; |
同时如果临时表涉及到动态分区的话,可以调整一下每一个节点支持处理的最大的分区数,不调整的话,并行度也上不去:
set hive.exec.dynamic.partition.mode=nonstrict; |
如果你有使用bucketing的话,关掉这个:
set hive.enforce.bucketing=true; |
如果用tez引擎的话,可以开启一下tez下自动调整并行度:
set tez.runtime.empty.partitions.info-via-events.enabled=true; |
总体来说hive的参数非常多,除了宏观那种多搞几个分区,增大内存之外,还有很多这种Job级别的参数,可能研究一下这些参数,效果更好。
扫码手机观看或分享: