7 억 개의 행을 동일한 값으로 업데이트


12

7 억 행 모두에 대해 열을 동일한 값으로 설정해야하는 데이터웨어 하우스 (oracle)가 있습니다.

관리자 액세스 권한이 없거나 관리자 액세스 권한이 없으므로 기본 SQL로 수행해야하며 임시 테이블을 만들지 않아야합니다.

더 복잡한 문제는 1 = 1 인 간단한 업데이트를하려고하면 리두 공간이 부족하다는 것입니다.

내가 지금 실행하는 방법은 다음과 같이 반복됩니다.

loop
  update mytable set mycolumn = '1' where mycolumn is null and rownum < 50000;
  commit;
end loop

그러나 나는 이것이 순진하고 더 빠르고 더 우아한 해결책이 있어야한다는 것을 알고 있습니다.


테이블이 분할되어 있습니까?
잭 topanswers.xyz 시도라고

나는 그렇게 믿지 않습니다. 몇 가지 색인이 있지만 업데이트 할 열과 관련된 것은 없습니다.
owook

답변:


4

공간이 있으면 최소 실행 취소 / 다시 실행을 사용하여 CTAS를 수행 할 수 있습니다 . 색인이 전혀 없다면 다른 방법으로 수행하는 것이 매우 느리고 미친 것처럼 로깅을 생성합니다.

보조 인덱스가없는 단일 IOT 또는 단일 테이블 클러스터가있는 경우 아직 업데이트되지 않은 필드를 찾기 위해 전체 테이블을 다시 스캔하지 않고도 청크에서 기본 / 클러스터 키 업데이트를 단계별로 수행 할 수 있습니다.

--편집하다

보조 테이블을 만들 수 없습니다 ... 두 개의 인덱스가 있지만 업데이트하는 열과 관련된 인덱스는 없습니다.

그런 다음 색인을 생성하는 대상을 사용하여 처리하기 위해 테이블을 청크로 분할하는 것이 좋습니다 (단일 열인 경우에도 값 범위로 분할 할 수 있음). 암호. 당신은 엄청나게 많은 리두와 함께 살아야하고 실행 취소 공간도 지울 것입니다.

--edit2

열을 추가 / 이름 바꾸기 / 삭제할 수 있으면 매우 효율적으로 수행 있지만 11g에서만 가능합니다.


1
DBA가 허용하면 NOLOGGING핫 스탠바이가 무효화됩니다.
Gaius

사실, 그리고 백업이 나중에 너무 좋은 생각 일 것이다 - 그러나 이것은 창고이며 nologging창고위한 도구입니다
잭 topanswers.xyz 시도라고

임시 테이블 인 경우에도 첫 번째 테이블보다 크지 않은 보조 테이블을 만들 수 없습니다.
owook

11g 링크가 유망 해 보였지만 60m 테이블의 경우 모든 행의 값을 설정해야하기 때문에 여전히 끔찍하게 느리다는 의견이 있습니다. 내 테이블의 크기가 10 배이므로이 방법은 개선되지 않을 수 있습니다.
owook

@owook no, 11g 에서이 작업은 빠르며 모든 행의 값을 "일부 테이블 유형 (예 : LOB 열이없는 테이블)"에 설정하지 않습니다 . 테이블의 부분 집합에 그것을 시도 ( create table foo as select * from bar where rownum<100000)
잭은 말한다 topanswers.xyz 시도

1

11g를 사용하는 경우 열을 삭제하고 기본값이있는 NOT NULL 열로 다시 추가하십시오. 이는 직관적이지 않지만 Oracle은 기본값을 테이블 정의에 저장하여 런타임시 기본값을 대체합니다.

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