OracleBulkCopy는 구체적으로 무엇을하며 성능을 어떻게 최적화 할 수 있습니까?


14

세부 사항을 요약하려면 : 공급 업체 (Oracle) 데이터베이스에 약 5 백만 개의 행을 스테이징해야합니다. OracleBulkCopy(ODP.NET)을 사용하여 500k 행의 배치에는 모든 것이 잘 되지만 최대 5M까지 확장하려고하면 1M 마크에 도달하면 크롤링 속도가 느려지고 더 많은 행이로드되면 점차적으로 느려집니다. 3 시간 정도 지나면 시간이 초과됩니다.

나는 (또한, 게시물의 많은 모순되는 것이이 테이블에 기본 키에 관련이 있지만 오라클 포럼 및 스택 오버플로 정보와 내가 모순을 읽고 있어요 무엇을 많이 트롤 어업을 봤는데 의심 서로 ) . 누군가 프로세스에 대한 밀접한 관련 질문에 대한 기록을 세울 수 있기를 바랍니다.

  1. 않는 OracleBulkCopy클래스는 기존의 또는 직접 경로로드를 사용할 수 있습니까? 이를 확인할 수있는 방법이 있습니까?

  2. 가정이 수행 사용 직접 경로로드 : 그것은 오라클은 자동으로 부하와 풋 다시 온라인 이후 그 동안 사용할 수없는 모든 인덱스를 설정한다는 사실인가요? 이 효과에 대한 몇 가지 진술을 읽었지만 다시 확인할 수는 없습니다.

  3. # 2가 true이면 대량 복사 작업을 시작하기 전에 테이블에 어떤 인덱스가 달라 집니까? 그렇다면 왜 그렇습니까?

  4. # 3과 관련하여 일반적으로 사용할 수없는 인덱스로 벌크로드와 실제로로드 전에 인덱스를 삭제하고 나중에 다시 생성하는 것 사이에는 실질적인 차이가 있습니까?

  5. # 2 인 경우 하지 올바른, 또는 내가 이해하지 못하는거야 몇 가지주의 사항이있는 경우, 그것은 어떤 차이 만들 것 명시 적으로는 벌크로드 전에 인덱스를 사용할 수 없게 한 다음 명시 적으로 나중에 그것을 다시?

  6. 더 많은 레코드가 추가됨에 따라 대량 빌드 작업이 점차 느리게 성장할 수있는 인덱스 빌드 이외의 다른 것이 있습니까? (대량 작업이 기록되지 않을 것으로 예상하지만 로깅과 관련이 있습니까?)

  7. PK / 인덱스를 먼저 삭제 하지 않고 성능을 향상시킬 수있는 다른 방법 이 없다면 , 인덱스가 완전히 사라지지 않도록하기 위해 어떤 단계를 수행해야합니까? 과정의 중간?


참고 : 복사되는 데이터는 테이블의 유일한 인덱스 인 PK에 따라 이미 정렬 된 순서입니다.
Aaronaught

소스에서 데이터를 읽는 데 DataReader를 사용하고 있습니까?
bernd_k

@bernd_k : 아니요, 메모리에서 완전히로드합니다. 확실히 문제의 원인은 아닙니다.
Aaronaught

답변:


13

며칠 더 많은 독서와 실험을했고 나는 (대부분) 많은 것들에 대답 할 수있었습니다.

  1. 나는 이것을 ODP.NET 문서 (아이 론적으로 문서 에 포함되어 있지 않음) 에 묻힌 것을 발견했다 OracleBulkCopy.

    ODP.NET 대량 복사 기능은 Oracle SQL * Loader와 유사하지만 동일하지 않은 직접 경로로드 방식을 사용합니다. 직접 경로로드를 사용하면 기존로드보다 빠릅니다 (기존 SQL INSERT문 사용).

    그래서 나타납니다 않습니다 직접 경로를 사용합니다.

  2. 이를 통해 대량 대량 복사 작업을 수행하고 SQL Developer에서 인덱스 속성을 가져 와서 확인할 수있었습니다. 대량 복사가 진행 되는 동안 색인 나타납니다 UNUSABLE. 그러나OracleBulkCopy.WriteToServer 인덱스 UNUSABLE 상태 에서 시작되면 실행을 거부 한다는 점 을 발견했습니다. 따라서 인덱스 를 비활성화하고 다시 작성하는 것만 큼 간단하면 초기 상태를 신경 쓰지 않아야하기 때문에 더 많은 일이 진행되고 있습니다.

  3. 인덱스가 제약 조건 인 경우 특히 차이 가 있습니다 . 위에 링크 된 설명서에서이 작은 보석을 찾았습니다.

    활성화 된 제약 조건
    Oracle 대량 복사시 기본적으로 다음과 같은 제약 조건이 자동으로 활성화됩니다.

    • NOT NULL
    • UNIQUE
    • PRIMARY KEY (널이 아닌 열에 대한 고유 한 제약 조건)

    NOT NULL제약 조건은 열 배열 빌드 시간에 확인됩니다. NOT NULL제한 조건 을 위반하는 행 은 거부됩니다.

    UNIQUE로드가 끝날 때 인덱스가 다시 작성되면 제한 조건이 확인됩니다. 인덱스가 UNIQUE제한 조건을 위반하면 인덱스 사용 불가능 상태로 남아 있습니다.

    문서는 어떻게되는지에 약간 흐릿한입니다 동안 , 특히 기본 키와, 부하,하지만 한 가지 확신 - 그것은 다르게 동작 기본 키 대 없이 하나. (가)부터 OracleBulkCopy행복하게 인덱스 제약 조건을 위반하는 수 (및에 인덱스를 펀트 것이다 UNUSABLE당신이 일을 끝낼 때 상태), 내 직감는 점입니다 구축 간단하지 대량 복사하는 동안 PK 인덱스를하지만, 검증 후에 때까지.

  4. 관찰 된 차이가 Oracle 자체에 있는지 또는 그저 기발한 것인지 확실하지 않습니다 OracleBulkCopy. 배심원은 아직이 일을하고 있습니다.

  5. OracleBulkCopy인덱스가 처음 UNUSABLE상태 인 경우 예외가 발생 하므로 실제로 문제가됩니다.

  6. 이 경우 있는 다른 요인은 내가 의해 발견, 인덱스 (특히 PK 인덱스), 여전히 가장 중요하다 :

  7. 동일한 스키마를 사용하여 전역 임시 테이블을 CREATE AS만든 다음 (을 사용하여 ) 임시 테이블로 대량 복사 한 다음 임시 테이블 INSERT에서 실제 테이블로 일반 이전 을 수행 합니다. 임시 테이블에는 인덱스가 없기 때문에 대량 복사는 매우 빠르게 이루어지며 INSERT데이터는 이미 테이블에 있기 때문에 최종 도 빠릅니다 (5M 행 테이블-테이블 복사 이후 아직 추가 힌트를 시도하지 않았습니다) 이미 1 분 미만이 소요됩니다).

    나는이 방법으로 임시 테이블 스페이스를 사용했을 때의 잠재적 인 영향을 확신하지 못하지만 지금까지 아무런 문제가 없었으며 행의 손상을 방지하는 대안보다 훨씬 안전합니다. 또는 색인.

    이것의 성공은 PK 인덱스가 문제라는 것을 분명히 보여줍니다. 이것은 임시 테이블과 영구 테이블 사이의 실질적인 차이이므로 성능 테스트 중에 0 행으로 시작했습니다.

결론 : ODP.NET을 사용하여 약 10 만 개가 넘는 행을 인덱스 된 Oracle 테이블에 대량 복사하려고하지 마십시오. 인덱스를 삭제 (실제로 필요하지 않은 경우)하거나 데이터를 다른 (인덱싱되지 않은) 테이블에 "사전로드"하십시오 .


기본 키 제약 조건을 확인하는 것이 확실하지 않습니다. 동일한 데이터를 Oracle 테이블에 2 번 대량 삽입하고 Select *는 2 개의 중복 행을 표시하려고했습니다. 이 상태에서는 삭제가 불가능하지만 테이블 잘라내기를 사용하면 정리 상태로 돌아갈 수 있습니다.
bernd_k

@bernd_k : Delete인덱스가이므로 가능하지 않습니다 UNUSABLE. 이는 대량 복사가 끝날 때 발생하는 제약 조건 검사의 결과입니다.
Aaronaught

PowerShell Skript을 실행하고 SQL Server 데이터 리더, 기본 키가있는 모든 대상 테이블에서 Oracle 데이터베이스로 대량 복사를 호출하고 최대 205278 행의 테이블에 문제가 없습니다. 그러나 세부 정보 테이블을 채우기 전에 먼저 마스터 테이블을 가득 채우는 것이 매우 신중합니다. 테이블에서 다른 인덱스를 제거하지 않았으며 테이블이 처음 비어있을 때 아무런 문제가 없습니다.
bernd_k

@bernd_k : 그렇습니다, 나는 그 볼륨에서 너무 많은 문제가 없었습니다 (마지막 단락 참조). 당신이 끔찍한 수백만에 도달 할 때입니다. 또한 각 대량 복사 후 언젠가 테이블을 비우면 차이가있을 수 있습니다 (이 테이블은 비우지 않고 추가되며 인덱스가 커질수록 인덱스가 느려지는 방법을 알고 있습니다).
Aaronaught

어쩌면 그것은 도움이됩니다alter session set skip_unusable_indexes = true;
Wernfried Domscheit

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.