zoukankan      html  css  js  c++  java
  • Oracle sql优化之分析函数优化标量子查询

    待优化语句如下

    select a.code as code, a.m_code as m_code,a.stktype as f_stype,a.e_year as e_year,
              b.sname as sname,a.c_date as c_date,to_char(sysdate,'YYYYMMDD') as createtime,
              to_char(sysdate,'YYYYMMDD') as updatetime,
             (select sum(valuef2) from a t where t.code=a.code and t.c_date between to_char(to_date(a.c_date,'YYYYMMDD')-180,'YYYYMMDD') and a.c_date and t.e_year=a.e_year) e70115_70011,
              (select sum(valuef1) from a t where t.code=a.code and t.c_date between to_char(to_date(a.c_date,'YYYYMMDD')-180,'YYYYMMDD') and a.c_date and t.e_year=a.e_year) e70104_70011,
              (select sum(valuef6) from a t where t.code=a.code and t.c_date between to_char(to_date(a.c_date,'YYYYMMDD')-180,'YYYYMMDD') and a.c_date and t.e_year=a.e_year) e70126_70011,
             (select sum(valuef2) from a t where t.code=a.code and t.c_date between to_char(to_date(a.c_date,'YYYYMMDD')-180,'YYYYMMDD') and a.c_date and t.e_year=a.e_year) e70131_70011,
            '-' as f_unit
    from a,b@link b
    where a.code = b.code
    and b.stype=2 and b.status=1 and c_date>to_char(sysdate-3,'YYYYMMDD')

    首先分析下标量子查询中的过滤条件:

    t.c_date between to_char(to_date(a.c_date,'YYYYMMDD')-180,'YYYYMMDD') and a.c_date

    该语句的目标实现c_date 180天内的数据汇总,因此可以分析函数表示为

    order by to_date(c_date,'YYYYMMDD') range between 180 preceding current row

    标量子查询的语句可改写为

    sum(valuef2) over(partition by a.code,a.year order by to_date(a.c_date,'YYYYMMDD') range between 180 preceding current row)

    而我们只需要三天内的数据,所以加上case判断

    case 
      when a.c_date>to_char(sysdate-3,'YYYYMMDD')
     then 
      sum(valuef2) over(partition by a.code,a.year order by to_date(a.c_date,'YYYYMMDD') range between 180   preceding current row)
    end

    最终整体语句可改写为

    select A.*,b.sname as sname,to_char(sysdate,'YYYYMMDD') as createtime,
    to_char(sysdate,'YYYYMMDD') as updatetime from
    (select a.code as code,a.m_code as m_code, a.stktype as f_stype,a.e_year as e_year, a.c_date as c_date,
    case 
      when a.c_date>to_char(sysdate-3,'YYYYMMDD')
     then 
      sum(valuef2) over(partition by a.code,a.year order by to_date(a.c_date,'YYYYMMDD') range between 180   preceding current row)
    end as f70115_70011,
    case 
      when a.c_date>to_char(sysdate-3,'YYYYMMDD')
     then 
      sum(valuef1) over(partition by a.code,a.year order by to_date(a.c_date,'YYYYMMDD') range between 180   preceding current row)
    end as f70104_70011,
    case 
      when a.c_date>to_char(sysdate-3,'YYYYMMDD')
     then 
      sum(valuef6) over(partition by a.code,a.year order by to_date(a.c_date,'YYYYMMDD') range between 180   preceding current row)
    end as f70126_70011,
    case 
      when a.c_date>to_char(sysdate-3,'YYYYMMDD')
     then 
      sum(valuef5) over(partition by a.code,a.year order by to_date(a.c_date,'YYYYMMDD') range between 180   preceding current row)
    end as f70131_70011,
    '-' as f_unit
    from a where a.c_date>= to_char(sysdate-3-180,'YYYYMMDD') ---缩小数据区间
    ) A inner join b@link B on(A.code=B.code) 
    where B.stype=2 and B.status=1 and A.c_date>=to_char(sysdate-3,'YYYYMMDD')

    随着数据量的增加该优化的效率越明显

  • 相关阅读:
    Linux workqueue疑问【转】
    Java中基础类库使用
    Sdut 2164 Binomial Coeffcients (组合数学) (山东省ACM第二届省赛 D 题)
    python中使用mahotas包实现高斯模糊
    ZOJ1372 POJ 1287 Networking 网络设计 Kruskal算法
    Android 属性动画(Property Animation) 全然解析 (下)
    MySQL搜索: WHERE 多条件
    点滴记录——Centos 6.5 yum安装Ganglia
    标准linuxserver搭建
    检查ORACLE的警告文件的脚本
  • 原文地址:https://www.cnblogs.com/zhulongchao/p/4570257.html
Copyright © 2011-2022 走看看