oracle的一个存储过程放在job中自动执行效率很慢,几秒钟处理一条记录,如果放到plsql中或者sqlplus中去执行速度很快,1万条记录大约在20秒钟;
数据库时oracle12c,rac环境,两个节点,服务器内存有32g,cpu多核心的,服务器及配置上应该没有问题,没有死锁,open_cursor设置为1000,配置如下:
我需要每分钟执行一次这个存储过程,但是现在每次执行都需要好长时间,处理的数据量也不是很大。
系统在oracle10g/11g下面都很正常,就是12c的rac环境下这样,实在是不知道什么原因。
哪位高人指点下,不胜感激。

解决方案 »

  1.   

    PROCEDURE autoprocuploadconsumerec
        AS
            
            out_msg         VARCHAR2 (1000);
            out_result      NUMBER;
            vplanstoptime   VARCHAR2 (128);
            vcount          NUMBER;
            visbalance      NUMBER;
            n_opcount       NUMBER;
            n_oddfare       NUMBER;
            n_subopcount    NUMBER;
            n_suboddfare    NUMBER;        CURSOR c1
            IS
                SELECT *
                  FROM (  SELECT *
                            FROM t_xfjla
                        ORDER BY a.id)
                 WHERE ROWNUM < 800;
        BEGIN
            out_msg := '';
          
             dbms_output.put_line( 'START PROCESS _CONSUME'|| to_char(SYSTIMESTAMP,'yy-mm-dd hh24:mi:ss:ff3') );       
                FOR c1_rec IN c1
                LOOP
                    SELECT NVL (COUNT (*), 0)
                      INTO vcount
                      FROM base_customers a
                     WHERE     a.customerid = c1_rec.customerid
                           AND a.dpid = c1_rec.dpid;  
                    --如果为正式账户,则锁住base_customers表中的行
                    IF vcount > 0
                    THEN
                        SELECT a.opcount,
                               a.oddfare,
                               a.subopcount,
                               a.suboddfare
                          INTO n_opcount,
                               n_oddfare,
                               n_subopcount,
                               n_suboddfare
                          FROM base_customers a
                         WHERE     a.customerid = c1_rec.customerid
                               AND a.dpid = c1_rec.dpid
                        FOR UPDATE   OF
                            a.opcount, a.oddfare, a.subopcount, a.suboddfare skip locked ;
                    END IF;
              
                    SELECT NVL (COUNT (*), 0)
                      INTO vcount
                      FROM rec_writeoff a
                     WHERE     a.customerid = c1_rec.customerid
                           AND a.dpid = c1_rec.dpid;                
           
                        pkg_rec_cust_acc.processconsumerec (c1_rec.customerid,                                                        
                                                            out_msg,
                                                            out_result);
                     
                        --记录处理成功,删除上传记录
                        DELETE rec_upload_consume
                         WHERE id = c1_rec.id;
     
                          dbms_output.put_line( 'END PROCESS REC_UPLOAD_CONSUME'|| to_char(SYSTIMESTAMP,'yy-mm-dd hh24:mi:ss:ff3') );
                    COMMIT;
                END LOOP;
              
           
        EXCEPTION
            WHEN OTHERS
            THEN
                ROLLBACK;
                out_msg := out_result || '_' || out_msg || '_' || SQLERRM;
                out_result := -1;
                  dbms_output.put_line( 'proceupdateoldflag' || OUT_MSG || to_char(SYSTIMESTAMP,'yy-mm-dd hh24:mi:ss:ff3') );
               
        END;我用的exec  dbms_scheduler做的job自动1分钟执行一次,目前每次总超过1分钟,plsql中执行速度很快
      

  2.   

    job执行的时候,看看有没有锁,看看v$session_wait有什么等待事件
      

  3.   

     一分钟执行一次为什么还要一条条记录执行,直接一批执行不就好啦?而且你这种没加监控时间,你自己都不知道你这个sql执行那一步比较慢
      

  4.   

    id 有索引没有,加个索引看看! base_customers 查询慢步 ,和 pkg_rec_cust_acc.processconsumerec 又是什么过程, FOR UPDATE   OF 不用可以不,加个日志运行记录临时表分段记录记录时间为毫秒,看看运行到哪个代码段慢了,就分析一下!