数据库
首页 > 数据库> > Oracle关于WINDOW SORT PUSHED RANK一些探究猜想

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