Oracle关于WINDOW SORT PUSHED RANK一些探究猜想
作者:互联网
Oracle关于WINDOW SORT PUSHED RANK一些探究猜想
最近遇到一条SQL,开发让我做出优化
with tmp as (select * from T_VERIFY_APPLY ty where ty.result_id in ('11', '12') and ty.sender_id = 'SWBHAP' and ty.create_time >= ADD_MONTHS(sysdate, -12) and ty.create_time <= sysdate), tmp1 as (select count(*) as month_call_num from tmp where to_char(sysdate, 'yyyy/mm') = to_char(tmp.create_time, 'yyyy/mm')), tmp2 as (select count(*) as last_year_month from tmp where to_char(ADD_MONTHS(sysdate, -12), 'yyyy/mm') = to_char(tmp.create_time, 'yyyy/mm')), tmp3 as (select count(*) as month_on_month from tmp where to_char(ADD_MONTHS(sysdate, -1), 'yyyy/mm') = to_char(tmp.create_time, 'yyyy/mm')), tmp4 as (select count(*) as this_year from tmp where to_char(sysdate, 'yyyy') = to_char(tmp.create_time, 'yyyy')), tmp5 as (select count(*) as past_year_num from tmp where to_char(ADD_MONTHS(sysdate, -12), 'yyyy') = to_char(tmp.create_time, 'yyyy')), temp as (select tl.entry_id, ty.create_time, ty.sender_id, row_number() over(partition by tl.entry_id order by 1) rn from t_verify_apply_list tl --418M left join T_VERIFY_APPLY ty --14M on ty.head_seq_no = tl.head_seq_no where ty.result_id in ('11', '12') and ty.sender_id = 'SWBHAP' and ty.create_time >= ADD_MONTHS(sysdate, -12) and ty.create_time <= sysdate), tmp6 as (select count(temp.entry_id) month_goods_num from temp where temp.rn = 1 and to_char(sysdate, 'yyyy/mm') = to_char(temp.create_time, 'yyyy/mm')), tmp7 as (select count(temp.entry_id) month_goods_with from temp where temp.rn = 1 and to_char(ADD_MONTHS(sysdate, -12), 'yyyy/mm') = to_char(temp.create_time, 'yyyy/mm')), tmp8 as (select count(temp.entry_id) this_month_goods_with from temp where temp.rn = 1 and to_char(ADD_MONTHS(sysdate, -1), 'yyyy') = to_char(temp.create_time, 'yyyy')), tmp9 as (select count(temp.entry_id) this_year_goods_with from temp where temp.rn = 1 and to_char(sysdate, 'yyyy') = to_char(temp.create_time, 'yyyy')), tmp10 as (select count(temp.entry_id) year_goods_than from temp where temp.rn = 1 and to_char(ADD_MONTHS(sysdate, -12), 'yyyy') = to_char(temp.create_time, 'yyyy')) SELECT tmp1.month_call_num, tmp2.last_year_month, tmp3.month_on_month, tmp4.this_year, tmp5.past_year_num, tmp6.month_goods_num, tmp7.month_goods_with, tmp8.this_month_goods_with, tmp9.this_year_goods_with, tmp10.year_goods_than from tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10;View Code
别看SQL很长,实际上“架构”很简单。我给优化成如下SQL了。
with tmp as (select count(case when to_char(ty.create_time, 'yyyy/mm') = to_char(sysdate, 'yyyy/mm') then 1 else null end) month_call_num, count(case when to_char(ty.create_time, 'yyyy/mm') = to_char(ADD_MONTHS(sysdate, -12), 'yyyy/mm') then 1 else null end) last_year_month, count(case when to_char(ty.create_time, 'yyyy/mm') = to_char(ADD_MONTHS(sysdate, -1), 'yyyy/mm') then 1 else null end) month_on_month, count(case when to_char(ty.create_time, 'yyyy') = to_char(sysdate, 'yyyy') then 1 else null end) this_year, count(case when to_char(ty.create_time, 'yyyy') = to_char(ADD_MONTHS(sysdate, -12), 'yyyy') then 1 else null end) past_year_num from T_VERIFY_APPLY ty where ty.result_id in ('11', '12') and ty.sender_id = 'SWBHAP' and ty.create_time >= ADD_MONTHS(sysdate, -12) and ty.create_time <= sysdate), temp as (select count(case when to_char(create_time, 'yyyy/mm') = to_char(sysdate, 'yyyy/mm') then 1 else null end) month_goods_num, count(case when to_char(create_time, 'yyyy/mm') = to_char(ADD_MONTHS(sysdate, -12), 'yyyy/mm') then 1 else null end) month_goods_with, count(case when to_char(create_time, 'yyyy') = to_char(ADD_MONTHS(sysdate, -1), 'yyyy') then 1 else null end) this_month_goods_with, count(case when to_char(create_time, 'yyyy') = to_char(sysdate, 'yyyy') then 1 else null end) this_year_goods_with, count(case when to_char(create_time, 'yyyy') = to_char(ADD_MONTHS(sysdate, -12), 'yyyy') then 1 else null end) year_goods_than from ( select /*+ no_merge */ create_time from ( select ty.create_time, row_number() over(partition by tl.entry_id order by 1) rn from t_verify_apply_list tl,T_VERIFY_APPLY ty where ty.head_seq_no = tl.head_seq_no and ty.result_id in ('11', '12') and ty.sender_id = 'SWBHAP' and ty.create_time >= ADD_MONTHS(sysdate, -12) and ty.create_time <= sysdate and tl.entry_id is not null ) where rn = 1) ) SELECT tmp.month_call_num, tmp.last_year_month, tmp.month_on_month, tmp.this_year, tmp.past_year_num, temp.month_goods_num, temp.month_goods_with, temp.this_month_goods_with, temp.this_year_goods_with, temp.year_goods_than from tmp, temp;View Code
两者等价,但是会引起wrong result的bug出来,这个后边在单独写一篇另说。
拿出原SQL中的部分,
select * from (select tl.entry_id, ty.create_time, ty.sender_id, row_number() over(partition by tl.entry_id order by ty.create_time) rn from t_verify_apply_list tl left join T_VERIFY_APPLY ty on ty.head_seq_no = tl.head_seq_no where ty.result_id in ('11', '12') and ty.sender_id = 'SWBHAP' and ty.create_time >= ADD_MONTHS(sysdate, -12) and ty.create_time <= sysdate) where rn = 1;
标签:SORT,sysdate,ty,create,RANK,char,PUSHED,time,yyyy 来源: https://www.cnblogs.com/PiscesCanon/p/16395574.html