1.减少distinct:
使用distinct容易造成数据倾斜问题,使用group by的子查询代替它。
2.map任务数量优化:
实际业务中往往存在大量的分区表,每个分区表都实际存储一定量的文件,其中必然有些分区的数据量很少。正常读取时往往有多少个文件就创建多少个map,此时可以通过设置一些参数,让sql语句在执行前先合并表文件。 -参数:
mapred.min.split.size.per.node = {设置一个节点中分片至少的大小}byte mapred.min.split.size.per.rack= {设置一个交换机中分片至少的大小}byte
mapred.max.split.size = {设置分片的最大大小}byte
hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat 设置hive先合并文件再执行
-效果: 假设我全部设置为100000000(相当于100M),经过配置后,hive会首先合并文件,切分成各种100M,最后再把剩下来的各个节点上的散碎数据合并到一起再生成几个分片。 还有一种情况,当一个map任务中处理数据量很大时(大小很小,但是条数很多),可以采用分桶法,先用一个查询语句把该表数据查出来分桶写入,再使用这个分桶表。相当于增加map任务数量,增加并行度。
3.并行度优化:
1.手动设置reduce数量 mapred.reduce.tasks
2.避免全局的聚合函数,使用聚合函数