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的值。其他的列是同样的道理。
 
 
烦请指正~
 
 

猜你喜欢

转载自www.cnblogs.com/eric-ln/p/12610030.html