hive之于数据民工,就如同锄头之于农民伯伯。hive用的好,才能从地里(数据库)里挖出更多的数据来。
用过hive的朋友,我想或多或少都有类似的经历:一天下来,没跑几次hive,就到下班时间了。
hive在极大数据或者数据不平衡等情况下,表现往往一般,因此也出现了presto、spark-sql等替代品。今天不谈其它,就来说说关于hive,个人的一点心得。
一. 表连接优化
1.将大表放后头
- Hive假定查询中最后的一个表是大表。它会将其它表缓存起来,然后扫描最后那个表。
- 因此通常需要将小表放前面,或者标记哪张表是大表:/streamtable(table_name) /
2.使用相同的连接键
- 当对3个或者更多个表进行join连接时,如果每个on子句都使用相同的连接键的话,那么只会产生一个MapReduce job。
3.尽量尽早地过滤数据
减少每个阶段的数据量,对于分区表要加分区,同时只选择需要使用到的字段。
- 尽量原子化操作
尽量避免一个SQL包含复杂逻辑,可以使用中间表来完成复杂的逻辑
二. 用insert into替换union all
- 如果union all的部分个数大于2,或者每个union部分数据量大,应该拆成多个insert into 语句,实际测试过程中,执行时间能提升50%
如:
insert overwite table tablename partition (dt= ....)
select ..... from ( select ... from A
union all
select ... from B union all select ... from C ) R
where ...;
可以改写为:
insert into table tablename partition (dt= ....) select .... from A WHERE ...; insert into table tablename partition (dt= ....) select .... from B WHERE ...; insert into table tablename partition (dt= ....) select .... from C WHERE ...;
三. order by & sort by
- order by : 对查询结果进行全局排序,消耗时间长。需要 set hive.mapred.mode=nostrict
- sort by : 局部排序,并非全局有序,提高效率。
四. transform+python
- 一种嵌入在hive取数流程中的自定义函数,通过transfor