一、我有集几亿条记录表,曾经要做借贷方合计的查询,向请教用游标与不用游标哪个效率高?   a.用游标CURSOR cursor_name IS select 借贷标志,sum(金额) from tab where 日期=..... group by 借贷标志;
   b.不用游标 ,用2个SQL查询:
    select sum(金额) into v_amt1 from tab where 日期=..... 借贷标志=‘1’;
    select sum(金额) from v_amt2 from tab where 日期=..... 借贷标志=‘2’;二、由于数据庞大,估计我一个存储过程处理5年的数据需要200小时才能完成。我的服务有8个CPU,请问按年份用5个进程并行处理要比一个进程处理5年的数据要快,是吗?

解决方案 »

  1.   

    索引、分区等都有,只是逻辑太复杂,数据量大得惊人!!其中有: select 发生额A,发生额B,余额A,余额B ,入帐日期A,入帐日期B,入帐时间A,入帐时间B
    into
            AMTa,AMTb,BALa, BALb, DATEa,DATEb,TIMEa,TIMEb,TIMECAPTIONA,TIMECAPTIONB
      from
    (
    select rank() over(partition by 帐号b order by 时间差 ) rk, c.* from
    (
    select  a.发生额 发生额A, b.发生额 发生额B,
    a.余额 余额A, b.余额 余额B, a.时间标签 时间标签A,b.时间标签 时间标签B,
    a.入帐日期 入帐日期A, b.入帐日期 入帐日期B,
    a.入帐时间 入帐时间A, b.入帐时间 入帐时间B,
    (a.发生额 -b.发生额) / b.发生额 as 差额比,
    b.帐号 帐号b,
    (to_date(b.入帐日期 || b.入帐时间,'yyyy-mm-dd HH24.MI.SS')- to_date(a.入帐日期 || a.入帐时间,'yyyy-mm-dd HH24.MI.SS')) *3600*24 as 时间差
    from PTHSADTL a ,PTHSADTL b where a.帐号=acc1  and a.借贷标志='1'  and abs( (to_number(a.发生额) - amt1 )/ amt1 )<0.5  
    and   b.帐号=acc2  and b.借贷标志='2'  and abs( (to_number(b.发生额) - amt1 )/ amt1 )<0.5
    and  to_date(a.入帐日期 || a.入帐时间,'yyyy-mm-dd HH24.MI.SS') <= to_date( b.入帐日期 || b.入帐时间,'yyyy-mm-dd HH24.MI.SS') and  to_date(a.入帐日期 || a.入帐时间,'yyyy-mm-dd HH24.MI.SS')
      between to_date(date2,'yyyy-mm-dd') - 15 and TO_DATE(date2||time2,'YYYY-MM-DDHH24.MI.SS')
    and  to_date(b.入帐日期 || b.入帐时间,'yyyy-mm-dd HH24.MI.SS')
      between to_date(date2,'yyyy-mm-dd') - 15 and TO_DATE(date2||time2,'YYYY-MM-DDHH24.MI.SS')    
    ) c
    where ABS(差额比)<0.1  -- order by  时间差 
    )
    where RK<=1
      

  2.   

    200小时?你怎么得到的?等了8天8夜?看最后的sql,你的输出肯定是rank() over(partition by 帐号b order by 时间差 )的第一个,这样, 我们能不能就只从 (帐号b 时间差 )的第一个 中间做查询呢?显然可以(估计使用materialized view会有很好的性能)
      

  3.   

     我感觉是to_date () 效率很低引起的
      

  4.   

    分析一下这个SQL的执行计划,看能否调优。
      

  5.   

    先分析一个执行计划看看,这么干说也没办法分析
    另外并不是所有SQL语句都是能优化的,如果结构的不合理,神仙也弄不出来
    我原来接触的业务才几百万,怎么也不行,必须改动结构增加一个冗余列才可能提高另外建议不要使用游标,对数据库的性能消耗比较大,
    还有就是数据库的一些参数上是否还有可优化的余地.
    还要看数据库的CPU,内存,磁盘阵列,等很多因素.
      

  6.   

    1、若“借贷标志”就1和2两种可能值,用游标性能影响不大。
    最好的方案是:
    select 
      sum(decode(借贷标志, '1', 金额, 0)) into v_amt1,
      sum(decode(借贷标志, '2', 金额, 0)) into v_amt2 
    from tab 
    where 日期=..... ;2、并行处理,对多表关联的SQL效果明显。
    几亿条记录,200小时,说明有很大的优化空间。
    1)单笔处理可否转化成批量处理
    2)确认是否合理使用表分区;
    3)确认是否建立索引,或者是否合理使用到索引;
    ……
      

  7.   

    SQL的执行计划用什么工具可以分析?
      

  8.   

    细看你的SQL,发现表PTHSADTL和PTHSADTL在做笛卡儿积运算。
    应该是你不小心遗漏了连接条件。
      

  9.   

    第一个问题:能不用游标就不要用游标,用游标的效率低 ? 
    其实游标很多地方都用,显示游标跟隐式游标。
    我觉得显示游标效率还高点。你所谓的不用游标我看很难,就连update都是隐式游标的,难道这你称为不用游标?