2011-03-30 3 views
2

우리는 3300 만 개의 행을 가진 상당히 넓은 테이블 BaseData를 가지고 있습니다. 그런 다음 모든 종류의 매개 변수를 포함하는 여러 다른 테이블에 조인하는 업데이트 쿼리가 있습니다. 일부 함수가 적용되고 원본 Id별로 그룹이 만들어지고 그 결과가 몇 개의 열로 BaseData 테이블에 다시 쓰여집니다.테이블 잠금이 Oracle 10g 엔터프라이즈에서 업데이트 문을 빠르게 실행합니까?

이 과정은 매우 느려서 속도를 높이는 방법을 모색 중입니다. 필자는 SQLServer에 대한 경험이 많기 때문에 오라클의 모든 내부 구조는 아직 모릅니다.

업데이트 중에 Oracle은 모든 행의 버전을 작성하므로 모든 oher 독자가 영향을받지 않는 행을 읽을 수 있습니다. 그러나 이것은 상당한 자원을 필요로합니다. 업데이트를 모든 테이블의 버전을 만들지 않도록 테이블에 쓰기 잠금을 설정할 수있는 방법이 있습니까?

큰 업데이트를 원한다면 다른 팁이 있습니까? 우리는 이미 그것을 일괄 처리했습니다. 각 배치는 테이블의 별도 파티션에 있으며 여러 업데이트가 병렬로 실행됩니다. 하지만 아직도 너무 느립니다.

+1

오라클은 행 일관성을 보장하기 위해 실행 취소 세그먼트를 사용하는 행 사본을 생성하지 않습니다. 조만간 대량 업데이트를 할 수있는 또 다른 방법을 제안 할 것입니다 ... – tbone

+0

성명 (또는 성명 자체)의 개요를 게시 할 수 있습니까? –

+0

안녕하세요, 오늘 늦게 힙합으로 다른 일로 정말 바쁩니다. – gjvdkamp

답변

3

오라클의 경우 테이블에 독점적 인 잠금을 설정해도 다른 세션이 데이터를 읽지 못하게되거나 읽기 일관성있는 데이터보기 생성 작업을 수행하지 않아도된다는 간단한 대답이 있습니다. 마찬가지로 오라클에서는 "더티 읽기"를 사용하도록 세션에 알릴 수 없습니다.

음, 첫 번째 질문은 느린 것입니다. 기능에 합류하고 적용하는 모든 작업입니까, 아니면 다시 쓰는 것입니까? 업데이트 내용과 비교하여 SELECT my_updated_resultset FROM BASEDATA JOIN...의 실적은 어떻습니까? BaseData 독자와 업데이트 프로세스간에 경합이 있음을 확인 했습니까? 또한 비즈니스에 너무 느리거나 생각보다 느립니다.

또 다른 옵션은 파티션 교환을 사용하여 업데이트를 수행하는 것입니다. 높은 수준의 개념은 다음과 같습니다

  • INSERT /*+ append */ INTO BASEDATA_XCHG SELECT my_updated_resultset FROM BASEDATA PARTITION (ONLY_ONE_PARTITION) JOIN...
    1. CREATE TABLE BASEDATA_XCHG as SELECT * FROM BASEDATA WHERE 1 = 0;이 BASEDATA_XCHG 테이블에 필요한 모든 인덱스와 제약 조건을 만듭니다.

    당신이 BASEDATA 테이블의 파티션의 행의 대부분을 업데이트하는 경우

  • ALTER TABLE BASEDATA EXCHANGE PARTITION (ONLY_ONE_PARTITION) WITH BASEDATA_XCHG
  • ,을 업데이트하지 않습니다 - 새 테이블을 만들고 그것을 밖으로 교환한다. 팀 고만 (Tim Gorman)은 "Scaling to Infinity"이라는 훌륭한 논문을 가지고 있는데,이 개념을보다 깊이있게 다루고 있습니다. 그것을 확인하고 싶을 수도 있습니다. 아담의 대답에 추가

    +0

    안녕하세요. 우리는 선택 사항이 업데이트보다 훨씬 빠르기 때문에 그 부분을보고있었습니다. 또한 처리량은 배치의 행 수가 기하 급수적으로 증가하는 것처럼 보입니다. 우리는 작업을 작은 배치로 재배정합니다. 사업을하기에는 너무 느립니다. 그래서 우리는이 속도를 정말로 높일 필요가 있습니다. 그 밖의 것들은 우리가 이것을 고치고 C++이나 calc를 사용하는 것과 관련이있다. 파티션 교환에 대해 살펴 보겠습니다. 다른 아이디어는 업데이트하지 않고 다른 테이블에 삽입하여 원본에 연결할 수있게하는 것입니다. – gjvdkamp

    3

    :

    를 실행하세요하여 업데이트 문에 계획을 설명하고 실행 계획을 확인합니다.

    조인 및 WHERE 조건을 지원하는 인덱스를 추가하면 쿼리의 속도가 빨라질 수 있습니다.

    오라클은 읽기 일관성을 위해 세그먼트 취소 사용
    1

    (읽기,의 SCN과 함께 더 많은 here)

    내가 사용하고있는 스테이징 영역이 아닌 "자극"인스턴스에서 실행중인이 대형 일괄 처리를 있으리라 믿고있어 다양한 프로세스가 많이 있습니다. 큰 테이블의 25 % 이상 (대략적인 수치)을 업데이트하는 경우 업데이트를 시도하는 것보다 CTAS (선택 테이블 만들기 ...)를 수행하는 것이 좋습니다. CTAS에는 새 테이블에 대한 업데이트 논리가 포함됩니다.끝나면 새 테이블에 인덱스/부여/etc를 추가하고 new를 old로 바꿉니다. 또한 CTAS에 병렬 힌트와 nologging을 추가하여 잠재적으로 더욱 빠르게 처리 할 수 ​​있습니다.

    +0

    UNDO를 생성 할뿐만 아니라 쿼리하는 테이블을 업데이트하는 경우 실행 취소를 적용해야만 테이블 시작 부분의 테이블을 볼 수 있습니다. –

    +0

    @Gary, Im은 업데이트를 피하고 새로운 테이블을 생성한다고 말합니다. – tbone

    관련 문제