Hive 数据处理技巧总结(一)
此篇文章是总结实际业务中遇到的计算场景问题。
hive 参数调优的文章很多,此篇文章不做类似方面的描述。
文章描述在数据统计场景中,可以通过hive 一些函数的组合使用,极大提高计算效率的方式。
选择一张表中的不同字段值转化为列
演示场景描述:
业务表表 A :
table A ( id int, create_date bigint )
日志表 B :
table B ( id int, type string, lat double, lng double )
type 的取值为 'type_1','type_2','type_3'。
希望最终得到结果
table C( id int, create_date, type_1_lat, type_1_lng, type_2_lat, type_2_lng, type_3_lat, type_4_lng )
type_1_lat 表示为type_1值时的lat值
方法一:
select a.*, b1.lat, b1.lng, b2.lat, b2.lng, b3.lat, b3.lng from A a left join ( select * from B where type = 'type_1' ) b1 on a.id = b1.id left join ( select * from B where type = 'type_2' ) b2 on a.id = b2.id left join ( select * from B where type = 'type_1' ) b3 on a.id = b3.id
这确实不失为一个方案,可是我们思考一下,如果type_N的、在日志表数据量很大的情况,不停的执行left join,在分布式计算中还是会存在大量的shuffle操作,执行效率会越来越低。
即使使用hive参数优化,不改变大量left join 的情况下,这样的优化空间也是有限的。
换个思路,方法二:
with c as ( select a.*, if(b.type = 'type_1',b.lat,'') as type_1_lat, if(b.type = 'type_1',b.lng,'') as type_1_lng, if(b.type = 'type_2',b.lat,'') as type_2_lat, if(b.type = 'type_2',b.lng,'') as type_2_lng, if(b.type = 'type_3',b.lat,'') as type_3_lat, if(b.type = 'type_3',b.lng,'') as type_3_lng from A a left join B b on a.id = b.id ) select id, concat_ws('',collect_list(type_1_lat)) as type_1_lat, concat_ws('',collect_list(type_1_lng)) as type_1_lng, concat_ws('',collect_list(type_2_lat)) as type_2_lat, concat_ws('',collect_list(type_2_lng)) as type_2_lng, concat_ws('',collect_list(type_3_lat)) as type_3_lat, concat_ws('',collect_list(type_3_lng)) as type_3_lng from c group by id
讲一下思路,这是一个有点巧的办法。
以 type_1_lat 举例子。
第一步相当于把两个表全部做左连接,但是在type_1上有值的那一行,其他的所有列一定是没有值的,采用空字符串进行代替。
第二部按照id进行聚合操作,两个函数分别操作的含义可以解释为,先将type_1_lat列合并为一个集合,此时这一列的集合里面,只有一个值,其他的都为空字符串,
然后将所有值在用空字符串进行拼接,最后得到的结果,仍然是type_1_lat的值。其他的列是同样的道理。
烦请指正~