1.JOIN优化
执行JOIN语句时,将大表放在右边,如果表小到可以全部加载到内存中,可以考虑执行map端的JOIN
2. Reducer数量
可以将Reducer最大值设置为n*0.95,n为TaskTracker数量
通过设置hive.exec.reducers.max可以增加Reducer数量,但是这样并不能直接增大Hive中作业的Reducer个数,HIve作业的Reducer个数由以下两个参数决定
hive.exec.reducers.bytes.per.reducer(默认1GB)
hive.exec.reducers.max(默认999)
Reducer个数公式为 个数= min(参数2,总输入数据量/参数1)
所以,如果输入数据在5GB。hive会开启5个Reducer,可以通过改变这两个参数来控制Reducer个数。
3.列裁剪
表test有a,b,c,d,e列,开启裁剪后,执行语句:
SELECT a,b FROM test WHERE a < 10;
hive将不会都去c,d,e列,减少读取开销
列裁剪配置项为hive.optimize.cp默认为true。默认开启列裁剪
4.分区裁剪
查询过程中减少不必要的分区
5. GROUP BY优化
并不是所有聚合都必须在Reduce端完成,很多聚合操作都可以先在Map端进行部分聚合
hive.map.aggr=true //是否在map端进行聚合,默认为true
hive.groupby.mapaggr.checkinterval = 100000 //在map端进行聚合操作的条目数目
6.解决数据倾斜
hive.groupby.skewindata = true 当设置为true时,hive会产生两个作业,作业1将key随机分发,并在Reduce阶段完成聚合操作,作业2再按key分发,保证同一个key进入同一个reduce中。
其中第一个作业reduce输出是经过聚合的,减少了第二个作业输入,思想和combine类似
7.合并小文件
hive.merge.mapfiles = true 是否合并map端的输出文件,默认为true
hive.merge.mapredfiles = true 是否合并reduce阶段的输出文件。默认false
hive.merge.size.per.task = 256000000 合并的文件的大小,默认256000000
8. MULTI-GROUP BY和MULTI-INSERT
Hive的MULTI-GROUP BY和MULTI-INSERT特有的语法可以在同一个查询中使用多个insert语句,比分开使用多个insert效率高。
FROM test
INSERT OVERWRITE TABLE test_a
SELECT a,COUNT(e) GROUP BY a
INSERT OVERWRITE TABLE test_b
SELECT b,COUNT(e) GROUP BY b
INSERT OVERWRITE TABLE test_c
SELECT c,COUNT(e) GROUP BY c
需要把from放前面
9. UNION ALL
利用UNION ALL合并多个MapReduce作业
SELECT * FROM (SELECT * FROM t1 GROUP BY c1,c2,c3 UNION ALL SELECT * FROM t2 GROUP BY c1,c2,c3) t3 GROUP BY c1,c2,c3
该语句含有3个Mapreduce作业,转化后
SELECT * FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t2)t3 GROUP BY c1,c2,c3
转化后为1个reduce作业
10. 并行执行eg:如果表1和表2 JOIN的结果与表3和表4JOIN的结果再JOIN,那么表1和表2的JION与表3和表4的JOIN相互独立,可以同时运行
Hive默认不考虑并行,可以通过设置hive.exec.parallel为true开启并行模式
11. 全排序
指定使用的partitioner和分发区间文件
set hive.mapred.partitioner = org.apache.hadoop.mapred.lib.TotalOrderPartitioner
set total.order.partitioner.path=/tmp/range_key
/tmp/range_key 是一个sequenceFile格式文件,指定了数据分发区间,生成分发文件区间可以通过分桶抽样生成
CREATE EXTERNAL TABLE range_keys(id int) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.binarysortable.BinarySortableSerDe' STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveNullValueSequenceFileOutputFormat' LOCATION '/tmp/range_key';
INSERT OVERWRITE TABLE range_keys SELECT DISTINCT id FROM source t_sale SAMPLETABLE (BUCKET 100 OUT OF 100 on rand()) s SORT BY id
12.TOPN
如果使用ORDER_BY ...LIMIT N的话,只会生成一个作业,所有数据集中到一个Reducer中进行全排序,,效率很低
如果使用SORT BY ... LIMIIT N的话,会生成两个作业,在第一个作业中,会按照SORT BY排序生成多个Reducer进行局部排序,并求TOPN,假设Reducer个数为N,那么第二个作业中会收到M*N条数据并进行排序再去TOPN。
或者通过使用 distribute by...sort by来代替OrderBy