优化sql不用in高效查询之留存用户统计

优化sql不用in高效查询,留存用户统计

留存:在互联网行业中,用户在某段时间内开始使用应用,经过一段时间后,仍然继续使用该应用的用户,被认作是留存用户。
思路一使用了in在所有中找符合条件的很费时间,数据量大的时候甚至查不出来。思路二按日期查询,查询速度很快2分钟之内。

Java + Oracle
结果展示:
优化sql不用in高效查询之留存用户统计_第1张图片

思路1:可用作校验数据准确性

2019-05-31 激活日期,2019-06-1 1天后留存,⚠️distinct很重要

--2019-05-31 激活日期,2019-06-1 1天后留存,⚠️distinct很重要
select count(distinct f_unique_flag) from t_event where trunc(f_launch_time,'dd') = to_date('2019-06-1','yyyy-MM-dd') 
 and  f_app_channel='0202' and f_unique_flag in(
select distinct f_unique_flag from(
select f_unique_flag,f_app_channel,min(f_launch_time) as f_launch_time from t_event where f_req_source='APP' 
group by f_unique_flag,f_app_channel
)where trunc(f_launch_time,'dd') = to_date('2019-05-31','yyyy-MM-dd') and  f_app_channel='0202' 
--and f_unique_flag in (select f_system_flag from t_flag where f_third_channel in('PS','FH','MN','JBP')) --是否来自3
)

优化思路2:日期分开查然后拼接

思路:查询当日激活数、1日后留存数,sql拼接;
b.firstt:激活日期
e.f_launch_time:留存日期
3:两个日期天数差
例(3日后留存):(trunc(e.f_launch_time)-trunc(b.firstt)=3)

--f_launch_time 激活时间
--f_app_channel 用户来源渠道
--f_unique_flag 用户唯一标识
/*****当日激活用户数****/
select trunc(f_launch_time,'dd') as f_time,f_app_channel,count(distinct f_unique_flag) as activate_user from(
select distinct f_unique_flag,f_app_channel,min(f_launch_time) as f_launch_time from t_event where f_req_source='APP' 
group by f_unique_flag,f_app_channel)
--⚠️特别注意:查询条件要放在外层,不然数据不对!!!
--where trunc(f_launch_time,'dd') = to_date('2019-05-25','yyyy-MM-dd') and  f_app_channel='0202'
group by trunc(f_launch_time,'dd'),f_app_channel

/*****1天后留存用户数******/
select trunc(c.firstt,'dd') as f_time,f_app_channel,count(distinct c.f_unique_flag) remain_1_user from 
(select distinct e.f_unique_flag,b.firstt,e.f_launch_time,e.f_app_channel from t_event e ,
(select distinct f_unique_flag,f_app_channel,min(f_launch_time) as firstt from t_event where f_req_source='APP' 
group by f_unique_flag,f_app_channel) b
where e.f_unique_flag=b.f_unique_flag and e.f_app_channel=b.f_app_channel and (trunc(e.f_launch_time)-trunc(b.firstt)=1)

创建视图View,java程序把View查出的数据录入到Table,页面使用直接查询Table会快很多。

/*
* 创建视图View,java程序把View查出的数据录入到Table,页面使用直接查询Table会快很多
* 当日激活数,1日后留存用户数,2日后留存用户数 拼接sql
*/
create or replace view v_app_remainuser as
select t.f_time,t.f_app_channel,t.activate_user,t1.remain_1_user,t2.remain_2_user
from (select trunc(f_launch_time,'dd') as f_time,f_app_channel,count(distinct f_unique_flag) as activate_user from(
select distinct f_unique_flag,f_app_channel,min(f_launch_time) as f_launch_time from t_event where f_req_source='APP' 
group by f_unique_flag,f_app_channel)
--where trunc(f_launch_time,'dd') = to_date('2019-05-25','yyyy-MM-dd') and  f_app_channel='0202'
group by trunc(f_launch_time,'dd'),f_app_channel
) t left join
(select trunc(c.firstt,'dd') as f_time,f_app_channel,count(distinct c.f_unique_flag) remain_1_user from 
(select distinct e.f_unique_flag,b.firstt,e.f_launch_time,e.f_app_channel from t_event e ,
(select distinct f_unique_flag,f_app_channel,min(f_launch_time) as firstt from t_event where f_req_source='APP' 
group by f_unique_flag,f_app_channel) b
where e.f_unique_flag=b.f_unique_flag and e.f_app_channel=b.f_app_channel and (trunc(e.f_launch_time)-trunc(b.firstt)=1)
) c
group by trunc(c.firstt,'dd'),f_app_channel
) t1 on t.f_time=t1.f_time and t.f_app_channel=t1.f_app_channel 
left join
(select trunc(c.firstt,'dd') as f_time,f_app_channel,count(distinct c.f_unique_flag) remain_2_user from 
(select distinct e.f_unique_flag,b.firstt,e.f_launch_time,e.f_app_channel from t_event e ,
(select distinct f_unique_flag,f_app_channel,min(f_launch_time) as firstt from t_event where f_req_source='APP' 
group by f_unique_flag,f_app_channel) b
where e.f_unique_flag=b.f_unique_flag and e.f_app_channel=b.f_app_channel and (trunc(e.f_launch_time)-trunc(b.firstt)=2)) c
group by trunc(c.firstt,'dd'),f_app_channel
) t2  on t.f_time=t2.f_time and t.f_app_channel=t2.f_app_channel

*本文工作后整理记录

你可能感兴趣的:(数据库,Oracle)