2011-09-30 2 views
1

개체 유형과 테이블이 해당 개체로 구성되어 있습니다. 그래서 여기에 우리가 간다 : 또한 일반적인 ETL principle에서 작동 PL/SQL 기능이있다반복의 가져 오기를 BULK COLLECT로 바꿉니다

create or replace type lpu.someobj_o as object 
(  
    name VARCHAR2(75),  
    enroll_date DATE, 
    id NUMBER(12) 
) 

CREATE OR REPLACE TYPE lpu."SOMEOBJ_T" IS TABLE OF someobj_o; 

. 다음은 코드 함수의 일부입니다.

for some_cursor_rec in some_cursor(startTime, recordInterval) loop 
    open some_cur2(some_cursor_rec.name, some_cursor_rec.id); 
    fetch some_cur2 into some_cursor_rec2; 
    if some_cur2%rowcount > 0 then 
    loop 
     pipe row (
     lpu.someobj_o(
     id => some_cursor_rec2.id, 
     name => some_cursor_rec2.name, 
     enroll_date => some_cursor_rec2.enroll_date 
    ) 
    ); 
     fetch some_cur2 into some_cursor_rec2; 
     exit when some_cur2%notfound; 
    end loop;  
    end if; 
    close some_cur2; 
end loop; 

좋습니다. 따라서 문제는 작은 성능입니다. 이 기능을 완료하는 속도를 어떻게 높일 수 있습니까? 나는 BULK COLLECT이 성능을 향상시켜야한다고 읽었습니다. 하지만 내 경우에는 어떻게 사용할 수 있습니까? 나는 BULK COLLECT을 시도했지만 컬렉션의 유형이 잘못되었다는 에러를주었습니다. 미리 감사드립니다. 정말 당신의 도움을 바랍니다!

+1

'BULK COLLECT' 조항이있는'FETCH' 문? http://download.oracle.com/docs/cd/E11882_01/appdev.112/e17126/tuning.htm#BCGGAGIF –

+0

파이프 라인 기능에서'대량 수집 (bulk collect) '사용의 이점에 대해 약간 회의적입니다. 한 번에 여러 행을로드하더라도 한 번에 한 행을 출력에만 파이프 할 수 있습니다. 그 문제에 관해서는, 함수에서 처리가 상당히 진행되지 않는 한, 왜 처음에는 파이프 라인 함수를 사용하고 있는지 질문해야합니다. – Allan

+0

성능 향상을 위해 필요한 경우 파이프 라인 기능을 거부 할 수 있습니다. 나에게 그걸 권하는거야? – kseen

답변

0

다음은 객체 유형으로 bulk collect into을 사용하는 기본적인 예입니다.

create or replace type someobj_o as object 
(  
    name varchar2(75),  
    enroll_date date, 
    id number(12) 
); 
/

create or replace type someobj_t is table of someobj_o; 
/

create table someobj_table of someobj_o; 

insert into someobj_table values(someobj_o('Joe', current_date, 100)); 
insert into someobj_table values(someobj_o('Jack', current_date, 101)); 
insert into someobj_table values(someobj_o('John', current_date, 102)); 

declare 
    v_objs someobj_t; 
begin 
    select someobj_o(name, enroll_date, id) 
    bulk collect into v_objs 
    from someobj_table; 

    dbms_output.put_line('number of objects in a collection = ' || v_objs.count); 
end; 
/

업데이트

위의 커서보다 같은 :

declare 
    type objcur_t is ref cursor; 
    v_objcur objcur_t; 
    v_objs someobj_t; 
begin 
    open v_objcur for 
    select someobj_o(name, enroll_date, id) 
    from someobj_table; 

    fetch v_objcur bulk collect into v_objs; 

    close v_objcur; 

    dbms_output.put_line('number of objects in a collection = ' || v_objs.count); 
end; 
/
+0

웹에서 비슷한 예를 보았습니다. 하지만 커서에서'someobj_table'을'BULK COLLECT INTO'로 채워야합니다. 이 기능을 어떻게 작동시킬 수 있습니까? – kseen

+0

유형이 귀하의 편집 케이스에 호환되지 않는 오류가 있습니다. – kseen

+0

@kseen : 코드를 잘라내어 SQLPLUS에 붙여 넣으면 Oracle 11.2.0.1.0에서 완벽하게 작동합니다. 실행중인 오라클 버전은 무엇입니까? – user272735

4

성능이 우려가 있다면, 당신은 당신의 두 커서를 함께보고 시작해야합니다.

현재는 some_cursor에서 한 번 쿼리를 실행 중이고에서 선택한 행만큼 커서를 some_cur2 커서에서 몇 번 실행하면 입니다. 그러면 성능 병목 현상이 발생할 가능성이 큽니다.

두 쿼리를 하나의 쿼리에 결합하고 루프에 대한 커서를 실행하면 (쿼리를 한 번만 실행 함) 자동으로 한 번에 100 개의 행을 대량으로 가져 오므로 한 번에 100 개의 행이 자동으로 페치됩니다. 실제 대량 변환을 수동으로 변환해야합니다.

감사합니다.
Rob.

+0

전에 복잡한 커서 하나를 사용해 보았습니다. 그리고 단 하나의 커서로 성능을 약간 내려 가고있었습니다. 함수는 약 1 초 후에 실행을 마쳤습니다. 이제 (두 개의 커서로) 우리는 0,1 초를 가야합니다. 첫 번째 커서는 약 5-15 개의 레코드를 가져오고 초 커서는 각 첫 번째 커서의 레코드에 대해 약 40-50 레코드를 반환합니다. 조언 좀 해줄 래? – kseen

+0

나의 충고는 우리가 그들을 볼 수 있도록 두 커서와 커서 하나와 그들의 계획을 게시하는 것입니다. 이 게시물의 조언을 따르십시오. https://forums.oracle.com/forums/thread.jspa?messageID=1812597 –

관련 문제