2015-01-26 10 views
0

현재 파일의 데이터를 테이블에 삽입하고 있습니다. 필자는 테이블에 데이터를 삽입하기 전에 데이터를 포맷합니다 (탭 제거/캐리지 리턴/특정 텍스트에 대한 char 코드 가져 오기 등). 먼저 레코드가 있는지 확인하고 업데이트가 있으면 업데이트해야합니다. 그렇지 않으면 레코드를 테이블에 삽입해야합니다.동시에 대량 삽입 및 업데이트 및 업데이트

내가 가지고있는 문제는 매우 오랜 시간이 걸린다는 것입니다. 나는 두 개의 파일을 가지고 있는데 하나는 500k 레코드 바로 아래에 있고 다른 하나는 4mil 이상이다. 내가 대량으로 수집 할 수 있다면 둘 다 할 수 있을까요?

E.G.

open c_cur; 
loop 
    fetch c_cur bulk collect into examp limit 50000; 
    exit when limit.count = 0 
    forall x in 1..limit.count 
    update table1 
    set... 
    where... 

    if sql%notfound then 
     insert into table1 
     values (...) 
    end if; 
    commit; 
end loop; 
close c_cur; 

이것은 가능합니까?

스테이징 테이블을 설정하고 거기에 파일을 덤핑하고 거기서 작업하는 것에 대해 들었습니다. 그게 더 나은 선택인가? 얼마나 많은 성능 향상을 주겠습니까?

또한 파일에서 테이블을 병합하지 않는 것이 좋습니다.

감사합니다.

+0

를 사용할 수 있습니다. [here] (http://www.morganslibrary.org/reference/plsql/array_processing.html#apfm)를 참조하십시오. – Aramillo

답변

0

이 작업을 수행하는 가장 좋은 방법은 파일을 기반으로 외부 테이블을 설정하는 것입니다 (데이터베이스 서버가 파일이 저장된 디렉토리를 볼 수 있도록해야합니다). 그렇게하면, 당신은 MERGE 문을 수행 할 수 있습니다 (벌크 수집이나 그와 유사한 것은 필요하지 않습니다; 그것은 비록 좀 더 효율적이라 할지라도 여전히 행 단위 접근법입니다).

다음 최상 (IMHO)은 파일의 데이터를 준비 테이블로로드 한 다음 준비 테이블을 기반으로 병합 문을 수행하는 것입니다.

0

당신은 당신은 FORALL의 조합을 사용하고 병합 할 수는 SQL %의 bulk_rowcount

--after forall update: 
for i in 1..examp.count loop 
    if sql%bulk_rowcount(i) > 0 then 
    examp.delete(i); -- record already updated - remove it from array 
    end if; 
end if; 

-- loop only non-deleted elements here 
forall i in indicies of examp 
    insert into ....