hive 优化(干货)
hive优化一般分为底层优化和sql优化
底层优化
hive 默认引擎为 MR ,涉及优化一般也为MR的优化,一般分为以下部分。
-
数据倾斜 set hive.groupby.skewindata=true;
-
小文件合并
是否合并Map输出文件:hive.merge.mapfiles=true(默认)
是否合并Reduce 端输出文件:hive.merge.mapredfiles=false(默认)
合并文件的大小:hive.merge.size.per.task=25610001000(默认 256000000) -
合理reducer数量 (注 易导致oom溢出 慎用)
-
分组聚合
hive.map.aggr=true(用于设定是否在 map 端进行聚合,默认值为真) hive.groupby.mapaggr.checkinterval=100000(用于设定 map 端进行聚合操作的条目数)
HQL优化
-
前提:数据量大
-
回滚:对于回滚的语句 在句首添加特殊标识 如
<!
表示回滚符,即第一次运行时不会应用直接跳过 (可用–替换<!),避免直接使用overwrite
。 -
分区:合理依据存储策略设置分区表,及清理策略。
-
判空函数:避免大量 判空函数 如
nvl
,coalesce
, 在数据量小和逻辑简单的sql 中还好,数据量一旦到达某程度,严重影响执行效率。 -
开窗函数:主要涉及排序开窗函数,如
rank()over()
,row_number()
等函数,这部分函数非必须情况下应避免使用,因为这些函数对内存的需求较大。 -
杜绝全表扫描:严格杜绝无意义的子查询且全表查询类的子查询。如
select a.id , b.name from ( select * from tmp ) a left join ( select * from tmp2 where name ='z3') b ;
对于以上情况应该 用哪个字段取哪个字段(对于所有情况适用)。
-
避免笛卡尔积 如
select a.id , b.name from tmp1 a , tmp2 b where a.id = b.id;
应该写为
select a.id , b.name from tmp1 a join tmp2 on a.id = b.id ;
特殊情况
-
代码逻辑复杂,设计子查询或临时表过度,数据量不是非常大的情况。
小表
join
大表,适时做数据落地,把数据落到实表中,减少压栈,从而提升效率。 -
数据量大,代码逻辑非常复杂,跑批通常3个小时以上的,建议重构。