现在的位置: 首页 > 综合 > 正文

oracle优化案例1-sidy

2014年01月08日 ⁄ 综合 ⁄ 共 2818字 ⁄ 字号 评论关闭

SQL:

select F_SCODE, --股票代码,
       F_SNAME, --股票简称
       F_STYPE, --证券代码
       F_MKTCODE, --市场代码
       CREATETIME, --当前表创建时间
       UPDATETIME, --原记录更新时间
       f_unit, --单位
       seq_si_stk_90007.nextval syntimestamp, --内部使用
       f_reporttime, --报告期
       F90045_90007 --公告日期
  from (SELECT b.scode F_SCODE, --股票代码
               b.sname F_SNAME, --股票简称
               b.stype F_STYPE, --证券代码
               b.mktcode F_MKTCODE, --市场代码
               TO_CHAR(SYSDATE, 'yyyymmdd') CREATETIME, --当前表创建时间
               TO_CHAR(SYSDATE, 'yyyymmdd') UPDATETIME, --原记录更新时间
               '' f_unit, --单位
               a.declaredate f_reporttime, --报告期
               a.publishdate F90045_90007, --公告日期
               row_number() over(partition by b.scode, a.pl_reporttype order by a.declaredate desc) rn
          FROM SDC_MEMORD A, SDC_SECURITY B
         WHERE A.stkcode = b.scode
           and a.stype = b.stype
           and b.stype in (2, 4, 3)
           and a.pl_reporttype in ('01','02','03','04')
           and a.declaredate >= to_char(sysdate - 30, 'yyyymmdd')
           and a.declaredate <> a.publishdate)
 where rn = 1

(1)、首先查询执行计划:

(1)、按照执行计划的执行顺序一步一步深入查看,发现id为6、7以驱动和被驱动关系来首先执行时6表是全表扫描,对于驱动表6如果走索引会剔除掉很多记录。

              经过分析表sdc_security表加上status字段(该字段1:有效;2:无效)会走索引,开发人员忘记加上了,虽然不加上不会影响业务,但是加上6表会走索引,这样会快很多。所以在where语句后加上status=1。执行计划发生了该变。

由执行计划可明显看出该表sdc_security走了索引,time、cpu、IO都下降了好多。

(2)继续分析执行计划:

发现表虽然都走索引了,但是出现了两次loop join。

这里要从业务上理解这里关联关系的作用,
对于a.declaredate <> a.publishdate这个条件很好奇,为什么要这样写,分析数据发现

可改为a.declaredate=a.publishdate,且这样后不用写窗口函数(这里涉及到很多业务知识,不详细说明了,有兴趣的可私聊);

修改后的sql:

SELECT b.scode F_SCODE, --股票代码
               b.sname F_SNAME, --股票简称
               b.stype F_STYPE, --证券代码
               b.mktcode F_MKTCODE, --市场代码
               TO_CHAR(SYSDATE, 'yyyymmdd') CREATETIME, --当前表创建时间
               TO_CHAR(SYSDATE, 'yyyymmdd') UPDATETIME, --原记录更新时间
               '' f_unit, --单位
               seq_si_stk_90007.nextval syntimestamp,
               --a.declaredate f_reporttime, --报告期
               case
               when a.pl_reporttype='01'   then substr(a.declaredate,1,4)||'0331'

               when a.pl_reporttype='02'   then substr(a.declaredate,1,4)||'0630'
               when a.pl_reporttype='03'   then substr(a.declaredate,1,4)||'0930'
               when a.pl_reporttype='04'   then substr(a.declaredate,1,4)||'1231'
               end f_reporttime,       --报告期
               a.publishdate F90045_90007 --公告日期
          FROM SDC_MEMORD A, SDC_SECURITY B
         WHERE A.stkcode = b.scode
           and a.stype = b.stype
           and b.stype in (2, 4, 3)
           and b.status=1
           and a.pl_reporttype in ('01','02','03','04')
           and a.declaredate >= to_char(sysdate - 10, 'yyyymmdd')
           and a.declaredate = a.publishdate;

执行计划:

由执行计划可以看出time、cpu、IO完全降到最低,优化后执行时间从20分钟降到13s左右,观察几天都是13s左右,给力呀!很爽!!

(3)、总结:本次优化涉及到技术层面的东西很少,大部门是对业务的理解。优化后执行时间从20分钟降到13s左右,观察几天都是13s左右,给力呀!

首先要查看执行计划,找出可疑点,比如不走索引拉,表关联有问题拉等等,再从技术层面和业务层面去修改方式。所以业务层面的优化有的时候比技术层面优化更彻底、更高效、更给力。

贴出来大家共同学习,也希望大师们给出更好的解决方法,谢谢!

 

抱歉!评论已关闭.