代码编织梦想

一.引言

给定数据表中包含用户 uid 和用户是否点击广告的标签 label,经常有需求统计用户的下发,打开 UV,PV,下面通过 Hive 实现统计并分析 distinct 与 group by 的性能与使用场景。

一.Distinct & 未分组

使用 distinct 计算用户打开的 PU,UV:

hive -e "
select dt,
sum(if(label='1',1,0)) as click_pv,
count(distinct case when label='1' then click.uid else NULL end) as click_uv,
count(label) as send_pv,
count(distinct click.uid) as send_uv from
(select label, dt, uid from $table where dt between '$st' and '$end') click
group by dt;
"

distinct 操作会将所有 uid shuffle 到同一个 reduce 上,当数据量很大时,任务执行会很慢。

任务开始时间为 2022-05-16 13:00:30,大概执行 1小时30分。

二.Group By && 未分组

使用 group by 先将 click_pv,click_uv 划定到 id 维度,再通过 group by 分组 sum 聚合

hive -e "
select dt,
sum(click_pv) click_pv,
sum(case when click_pv>0 then 1 else 0 end) click_uv,
sum(send_pv) send_pv,
sum(case when send_pv>0 then 1 else 0 end) send_uv from
(select dt, uid,
sum(if(label='1',1,0)) as click_pv,
count(1) as send_pv
from $table
where dt between '$st' and '$end'
group by dt,uid
) click
group by dt;
"

group by 可以将数据分组再聚合,适合数据量比较大的场景,在数据很大的情况下效率优于 distinct。

任务开始时间为 2022-05-16 13:00:30,大概执行时间为 1小时,可以看到同样数据大小(大数据量)的情况下,groupby 的性能优于 distinct。

三.Distinct & 分组

增加 case when 语法即可增加 group。

hive -e "
select dt,group,
sum(if(label='1',1,0)) as click_pv,
count(distinct case when label='1' then click.uid else NULL end) as click_uv,
count(label) as send_pv,
count(distinct click.uid) as send_uv from
(select label, dt, uid,
case
    when substr(uid,-2,1) in ('0', '1') then 'A'
    when substr(uid,-2,1) in ('2', '3') then 'B'
    when substr(uid,-2,1) in ('4', '5') then 'C'
    when substr(uid,-2,1) in ('6', '7') then 'D'
    when substr(uid,-2,1) in ('8', '9') then 'E'
end group
from $table where dt between '$st' and '$end') click
group by dt,group;
"

任务开始时间为 2022-05-16 14:54:34,执行耗时约为 30分,如果想获取上面同样的结果,时间由 1h30min 缩短为 30min,所以增加 group 对性能的提升很大。

四.Group By & 分组

使用 group by 分组时需要在 select 逻辑以及 group by 的逻辑内都增加 case when 语法获取不同 uid 的分组,这里和上面一样,将全部用户分成 5 个组。

hive -e "
select dt,group,
sum(click_pv) click_pv,
sum(case when click_pv>0 then 1 else 0 end) click_uv,
sum(send_pv) send_pv,
sum(case when send_pv>0 then 1 else 0 end) send_uv from
(select dt, uid,
sum(if(label='1',1,0)) as click_pv,
count(1) as send_pv,
case
    when substr(uid,-2,1) in ('0', '1') then 'A'
    when substr(uid,-2,1) in ('2', '3') then 'B'
    when substr(uid,-2,1) in ('4', '5') then 'C'
    when substr(uid,-2,1) in ('6', '7') then 'D'
    when substr(uid,-2,1) in ('8', '9') then 'E'
end group
from $table
where dt between '$st' and '$end'
group by dt,uid,
case
    when substr(uid,-2,1) in ('0', '1') then 'A'
    when substr(uid,-2,1) in ('2', '3') then 'B'
    when substr(uid,-2,1) in ('4', '5') then 'C'
    when substr(uid,-2,1) in ('6', '7') then 'D'
    when substr(uid,-2,1) in ('8', '9') then 'E'
end
) click
group by dt,group;
"

由于增加了分组 group,最后新增了 job1 实现不同 group 的汇总,任务开始时间为 2022-05-16 14:51:00,执行耗时约为 8分。如果想要获取上面 Group By && 未分组的同样结果,只需要将 Group By && 分组的结果相加即可,而执行的时间由 1小时 缩短为 8分钟,相差了接近7倍,所以在选择到合适的分组 group 大小时,任务的执行时间可以大大缩短。 

 

五.总结

上面给出了 Group  By && Distinct 求 UV,PV 的方法,通过增加 group 和不增加 group 可以看到二者性能存在很大的不同,实战中可以使用二分法快速试验出合适的 group 数量再聚合,除此之外也可以手动指定 reduce 数量:

set mapred.reduce.tasks=100;

相关 Hive 参数可以参考 Hive 常用参数整理

方法耗时
distinct 90min
group by60min
distinct + group30min
group by + group8min

通过4组实验以及耗时可以得出大数据情况下:

A.Group By 效率优于 Distinct

B.Group By + group 效率优于 Group By

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/BIT_666/article/details/124798817

hive的multi-distinct可能带来性能恶化之案例优化-爱代码爱编程

目前hive的版本支持multi-distinct的特性,这个在用起来比较方便,但是在此特性下面无法开启防数据倾斜的开关(set hive.groupby.skewindata=true),防止数据倾斜的参数只在单distinct情况下会通过一个job来防止数据的倾斜。multi-distinct使用起来方便的同时也可能会带来性能的不优化,如日志中常常统计

10分布式数据仓库 hive -- hive案例实战1 apache common日志分析-爱代码爱编程

1 日志分析场景 某网站的apache common每天产生一个日志日志文件。将每一天的日志文件,按照日期作为分期,导入HIVE数据仓库。通过hive分析网站用户行为,如:PV,注册数,UV ip                          时间                                           访问地址    

hive使用技巧(三)——巧用group by实现去重统计-爱代码爱编程

相关文章推荐: hive使用技巧(一)自动化动态分配表分区及修改hive表字段名称 hive使用技巧(二)——共享中间结果集 hive使用技巧(三)——巧用group by实现去重统计 hive使用技巧(四)——巧用MapJoin解决数据倾斜问题 Hive使用技巧(五)—— 一行转多行,多行转一行 网站统计中常用的指标,p

hive做一个pv,uv统计的案例记录_madman1990的博客-爱代码爱编程_如何统计pv

hive学习记录 使用hive统计一个网站的pv,和uv,只有源文件,从导入文件到最后导出统计结果,统计一个网站某天某时的pv uv访问值。 步骤 在hive中新建数据源表。导入源文件到hive表中。对hiv

hive针对distinct的优化_吃鱼的羊的博客-爱代码爱编程

hive针对count(distinct xxx)只产生一个reduce的优化。 0x00 造成的原因 由于使用了distinct,导致在map端的combine无法合并重复数据;对于这种count()全聚合操作时,即使设定了reduce task个数,set mapred.reduce.tasks=100;hive也只会启动一个reducer。这就造

hive(27):分析网站uvpv等多指标综合案例_raybreslin的博客-爱代码爱编程

一、实现功能 1.分析网站日志,获得日期,uv,pv,登录人数,游客人数,平均访问时长,二跳率,独立ip数等关键信息。 其中: 登录:userid有值,会员,有账号登录 游客:userid无值,非登录人员 平均访问时长:在网页停留时间 二跳率:在一次会话中,同一个session点击的页面大于等于2的会话就是二跳(判断同一个session有多条记录的几率

HIVE SQL 启动hive,hive基础语句,求pv,uv-爱代码爱编程

第十一单元 HIVE SQL 、Hive MR参数设置 1、知识点回顾 hive数据库是hdfs上的文件夹,表也是文件夹,表里的数据是文件 hive建表 create table 表名(字段1 类型1,字段2 类型2……) row format delimited fields terminated by '字段分隔符'; 为一键启动集群中的zo

Hive-性能优化-爱代码爱编程

一、效率低下的原因 1、数据倾斜 2、关联操作,job数太多 3、小文件太多,导致map性能差 数据倾斜是指,在数据量大的情况下,效率较低。比如count(distinct)是按group by 字段分组,按distinct字段排序,一般这种分布方式是很倾斜的。举个例子:比如男uv,女uv,像淘宝一天30亿的pv,如果按性别分组,分配2个reduce,

hive--GROUPING SETS方法产生的聚合问题-爱代码爱编程

--- 这是计算pv uv指标 select COALESCE(activity_id,'ALL') as activity_id , COALESCE(page_name,'ALL') as page_name , COALESCE(product,'ALL

hive 创建访问用户_HIVE大数据实战项目---用户行为分析-爱代码爱编程

一、项目需求 本案例的数据为小程序运营数据,以行业常见指标对用户行为进行分析,包括UV、PV、新增用户分析、留存分析、复购分析等内容。 项目需求如下: 1.日访问量分析,并观察其走势 2.不同行为类型的访问量分析 3.一天中不同时间段的访问量分析(时间段按小时划分) 4.每日新增用户情况分析 5.用户留存分析 6.复购分析 7.商品排

MYSQL统计UV和PV_日志分析_统计每日各时段的的PV,UV-爱代码爱编程

第一步: 需求分析 需要哪些字段(时间:每一天,各个时段,id,url,guid,tracTime) 需要分区为天/时 PV(统计记录数) UV(guid去重) 第二步: 实施步骤 建Hive表,表列分隔符和文件保持一至 Load数据到Hive表中 写HiveSql进行统计,将结果放入Hive另一张表中(数据清洗) 从Hive的另一张

mysql 统计 uv pv_结合Hive、Sqoop统计日志pv和uv-爱代码爱编程

分析 数据源格式 121508281810000000 http://www.yhd.com/?union_ref=7&cp=0 3 PR4E9HWE38DMN4Z6HUG667SCJNZXMHSPJRER VFA5QRQ1N4UJNS9P6MH6HPA76SXZ737P 10977119545 124.65.159.122 unionKe

mysql一天内每个小时的pvuv_基于Hive及Sqoop的每日PV、UV、IP定时分析-爱代码爱编程

[Author]: kwu 基于Hive及Sqoop的每日PV、UV、IP定时分析 1、创建pvuvip的hive表 hive -e " use stage; CREATE EXTERNAL TABLE pvuvip( day string, pv int, uv int, ipcnt int ) ROW FORMAT DELIM

大数据--hive6--实战训练之获取数据并插入到表中-爱代码爱编程

目录 一:获取数据并且插入到表中 二.命名空间 三.通过set设置一些参数以及负载均衡总结 四.分区和concat_ws用法 五.cast和coalesce和case when 的用法 六.使用explode()和group by配合使用进行分组 一:获取数据并且插入到表中 use namespace hehe; // 名称 set map

大数据场景下使用SQL求UV和PV的问题-爱代码爱编程

表数据 现有user_age表如下: user_app表如下: 需求 求:0-10岁的用户、11-20岁的用户、21-30岁的用户、30岁以上的用户使用app的人数(uv)和次数(pv)。 分析 需求乍一看不难,但是如何实现同时求出uv和pv?有的同学可能最先想到的就是uv = count(distinct uid),pv = count(*)。