暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 呼叫过程需要时间

ASKTOM 2020-05-01
298

问题描述

嗨,先生,

希望您一切顺利,并感谢您提供oracle支持,非常感谢您的努力。
目前,我在生产中遇到一个问题,因此无法在此处复制代码,但我在下面写了以供参考。
我有1个过程,其中数据插入正在处理多个表,当我调用prc 1记录插入表中有多个表与某些条件这个过程的单一调用运行更快或在几秒钟内,我们可以说。但是我想称它为10万时间,因为我必须创建10万记录进行一些测试。
我正在使用循环调用prc,但是它非常慢,因为仅创建2k记录需要20分钟。打电话给中华人民共和国还有别的选择吗?

如下是逻辑,但实际上有很多验证块和多次插入
注意: 对于单个调用,它以秒为单位运行,但是在循环中调用2k次时,需要apprx 20分钟,并且在表中没有触发器

-------------------------------------------------------------------------------------------------
CREATE TABLE BLK_EMP 
( 
EMP_BATCH VARCHAR2(10 BYTE), 
EMP_ID  NUMBER, 
E_RECID NUMBER, 
DEPTNO  NUMBER
);
/

create or replace TYPE e_address_obj AS OBJECT (    address     VARCHAR2(50),  
pincode NUMBER);
/

create or replace TYPE emp_addr_tab as table of e_address_obj;
/

create table t_rec
as
select (9876234+level) as eid
from dual
connect by level <= 300;
/

create sequence seq_emp_id;
/

--prc

create or replace package pkg_emp_addr
as

  procedure prc_emp_addr(
                       in_batch_emp IN varchar
                       ,in_empno IN NUMBER 
                       ,in_empaddr IN emp_addr_tab
                       ,in_e_recid IN NUMBER
                       ,in_out_deptno IN OUT NUMBER
                       );

end pkg_emp_addr;
/
create or replace PACKAGE BODY PKG_EMP_ADDR AS

  procedure prc_emp_addr(
                        in_batch_emp IN varchar
                       ,in_empno IN NUMBER 
                       ,in_empaddr IN emp_addr_tab
                       ,in_e_recid IN NUMBER
                       ,in_out_deptno IN OUT NUMBER
                       ) 
AS

L_DEPTNO  NUMBER;
l_seq_emp_id number;
--l_table emp_addr_tab := emp_addr_tab();
  BEGIN
    
    L_DEPTNO := in_out_deptno;
    
    IF L_DEPTNO IS NOT NULL
        THEN
        SELECT DEPTNO INTO in_out_deptno
        FROM EMP
        WHERE EMPNO = 7499;
    ELSE 
    in_out_deptno := 101;
    END IF;
    
           
    l_seq_emp_id := seq_emp_id.nextval;
    insert into blk_emp values(in_batch_emp, l_seq_emp_id, in_e_recid, in_out_deptno);
    --commit;
    
    exception 
    when others then
    rollback;
    raise_application_error(-20001,sqlerrm);
    
  END prc_emp_addr;

END PKG_EMP_ADDR;
/

---calling it

declare
in_batch_emp  varchar(2);
in_empno   NUMBER;
in_out_deptno  NUMBER;
TYPE myarray IS TABLE OF number;
l_data myarray;
emp_add_t emp_addr_tab;
CURSOR r IS
SELECT eid
FROM t_rec;
begin

emp_add_t := emp_addr_tab();
emp_add_t.extend(3);
emp_add_t(1) := e_address_obj('usa',440022);
emp_add_t(2) := e_address_obj('ind',401122);
emp_add_t(3) := e_address_obj('germany',662200);

    for a in 1..1000
    loop
        
        open r;
        loop
            fetch r bulk collect into l_data limit 100;
            for i in 1..l_data.count
            loop 
                    for idx IN emp_add_t.FIRST .. emp_add_t.COUNT
                    LOOP
                           in_out_deptno := null;
                           PKG_EMP_ADDR.prc_emp_addr(
                                                        'c'
                                                        ,0
                                                        ,emp_add_t
                                                        ,l_data(i)
                                                        ,in_out_deptno
                                                     );
                    END LOOP;
            end loop;
        exit when r%notfound;
        end loop;
        close r;  
    end loop;
  
commit;
exception 
when others then
raise_application_error(-20001,sqlerrm);
end;
/


数组也存在,但未在上述过程中使用,仅用于调用引用
-- 添加了对象类型

专家解答

你正在做一整堆单行操作 ....你想看看在布景中做事。数据库的工作原理 (最好) 与集合不与行。

对于exmaple,您可以在For-idx循环后的单个操作中完成所有emp_batch插入

SQL>
SQL> create or replace package pkg_emp_addr
  2  as
  3    type batch_list is table of blk_emp%rowtype
  4       index by pls_integer;
  5
  6    g_batch_list batch_list;
  7
  8    procedure prc_emp_addr(
  9                         in_batch_emp IN varchar
 10                         ,in_empno IN NUMBER
 11                         ,in_empaddr IN emp_addr_tab
 12                         ,in_e_recid IN NUMBER
 13                         ,in_out_deptno IN OUT NUMBER
 14                         );
 15
 16    procedure batch_insert;
 17  end pkg_emp_addr;
 18  /

Package created.

SQL>
SQL> create or replace PACKAGE BODY PKG_EMP_ADDR AS
  2    g_default_deptno int;
  3
  4    procedure prc_emp_addr(
  5                          in_batch_emp IN varchar
  6                         ,in_empno IN NUMBER
  7                         ,in_empaddr IN emp_addr_tab
  8                         ,in_e_recid IN NUMBER
  9                         ,in_out_deptno IN OUT NUMBER
 10                         )
 11  AS
 12
 13  L_DEPTNO  NUMBER;
 14  l_seq_emp_id number;
 15  --l_table emp_addr_tab := emp_addr_tab();
 16    BEGIN
 17
 18      L_DEPTNO := in_out_deptno;
 19
 20      IF L_DEPTNO IS NOT NULL
 21      THEN
 22          in_out_deptno := g_default_deptno;
 23      ELSE
 24          in_out_deptno := 101;
 25      END IF;
 26
 27
 28      l_seq_emp_id := seq_emp_id.nextval;
 29      g_batch_list(g_batch_list.count+1).EMP_BATCH := in_batch_emp;
 30      g_batch_list(g_batch_list.count).EMP_ID := l_seq_emp_id;
 31      g_batch_list(g_batch_list.count).E_RECID := in_e_recid;
 32      g_batch_list(g_batch_list.count).DEPTNO:= in_out_deptno;
 33
 34      exception
 35      when others then
 36      rollback;
 37      raise_application_error(-20001,sqlerrm);
 38
 39    END prc_emp_addr;
 40
 41    procedure batch_insert is
 42    begin
 43      forall i in 1 .. g_batch_list.count
 44         insert into blk_emp values g_batch_list(i);
 45    end;
 46
 47  begin
 48    SELECT DEPTNO INTO g_default_deptno
 49          FROM EMP
 50          WHERE EMPNO = 7499;
 51  END PKG_EMP_ADDR;
 52  /

Package body created.

SQL>
SQL> ---calling it
SQL>
SQL> set serverout on
SQL> declare
  2  in_batch_emp  varchar(2);
  3  in_empno   NUMBER;
  4  in_out_deptno  NUMBER;
  5  TYPE myarray IS TABLE OF number;
  6  l_data myarray;
  7  emp_add_t emp_addr_tab;
  8  CURSOR r IS
  9  SELECT eid
 10  FROM t_rec;
 11  begin
 12
 13  emp_add_t := emp_addr_tab();
 14  emp_add_t.extend(3);
 15  emp_add_t(1) := e_address_obj('usa',440022);
 16  emp_add_t(2) := e_address_obj('ind',401122);
 17  emp_add_t(3) := e_address_obj('germany',662200);
 18
 19      for a in 1..100 -- 1000
 20      loop
 21
 22          open r;
 23          loop
 24              fetch r bulk collect into l_data limit 100;
 25              for i in 1..l_data.count
 26              loop
 27                      pkg_emp_addr.g_batch_list.delete;
 28
 29                      for idx IN emp_add_t.FIRST .. emp_add_t.COUNT
 30                      LOOP
 31                             in_out_deptno := null;
 32                             PKG_EMP_ADDR.prc_emp_addr(
 33                                                          'c'
 34                                                          ,0
 35                                                          ,emp_add_t
 36                                                          ,l_data(i)
 37                                                          ,in_out_deptno
 38                                                       );
 39                      END LOOP;
 40                      PKG_EMP_ADDR.batch_insert;
 41
 42
 43              end loop;
 44          exit when r%notfound;
 45          end loop;
 46          close r;
 47      end loop;
 48
 49  commit;
 50  exception
 51  when others then
 52  raise_application_error(-20001,sqlerrm);
 53  end;
 54  /

PL/SQL procedure successfully completed.

SQL>
SQL>


文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论