2012-12-08 3 views
4

저는 postgresql DB와 거의 10 억 개의 행을 가진 테이블을 가지고 있습니다. 나는 기본 값으로 새 열을 추가 할 때 는 :거대한 테이블에 DEFAULT 값이있는 열을 추가하십시오.

ALTER TABLE big_table 
ADD COLUMN some_flag integer NOT NULL DEFAULT 0; 

거래는 30 + 분 .. 그리고 DB 로그를 계속 경고를 촬영하기 시작합니다.

검색어를 최적화하는 방법은 무엇입니까?

+1

로그 파일에 어떤 경고가 표시됩니까? –

+0

데이터로 표의 복사본을 만들고 그 표에 열을 추가 한 다음 두 표의 이름을 바꾸어 바꿀 수 있습니다. (의존성을 적절하게 처리해야 할 수도 있습니다.) – dezso

+0

@dezso 우리는 10 억 개의 행을 사용 중입니다. 어떻게하면 프로 시저를 더 빠르게/더 효율적으로 만들 수 있습니까? –

답변

6

(아직 시간이 걸릴 것이다) 일괄 적으로 그 일 외에도 : 당신은 COPY 문으로 테이블을 덤프하고 다른 열을 삽입 할 COPY 문의 내용을 편집하는 스크립트를 작성할 수

(COPY가 될 수 있습니다 CSV IIRC).

그런 다음 변경된 COPY 덤프를 다시로드하면 COPY가 트랜잭션을 기록하지 않기 때문에 이론적으로 ALTER보다 빠릅니다.

다른 옵션은 명령을 실행하는 동안 fsync을 해제하는 것입니다 ... 다시 켜는 것을 잊지 마십시오.

위의 두 가지를 모두 일괄 적으로 수행 할 수도 있습니다.

+0

고마워, 나는 더 많은 쿼리 건설 트릭을 원했지만 그것이 아닌 것 같습니다. 나는 다음 번에 Fsync를 고려할 것이다. –

+0

하루의 끝에서 10 억은 10 억입니다. 그것은 작은 숫자가 아닙니다 :). 데이터가 무엇인지 궁금합니다. –

+0

RL 문서의 구문 분석 된 데이터를 나타냅니다. 확실히 더 나은 스토리지 개념이지만 전체 구조를 변경하는 것은 옵션이 아닙니다. –

4

기본값없이 열을 작성하고 간헐적 인 커밋을 사용하여 일괄 적으로 행을 수동으로 업데이트하여 기본값을 적용하는 것이 좋습니다.

+0

동일하게 생각하고 있었지만 이것은 아마도 더 많은 시간이 걸릴 것입니다. 그리고 나는 그것을 "버전 업데이트"거래에 넣어야합니다. 그래서 나는 더 깨끗한 해결책을 찾고 있습니다. –

+1

새 컬럼에 널이 아닌 값을 가져 오려면 한 행 또는 다른 모든 행을 복사해야합니다. 'ALTER TABLE'에서 기본값을 지정함으로써 다른 모든 액세스를 차단하면서 동시에 모든 작업을 수행 할 수 있습니다. 다른 프로세스가 컬럼을 널 (null) 가능으로 추가하고 일련의 작은 갱신을 수행하여 테이블을 액세스하는 동안 점진적으로 수행 할 수 있습니다. 전체 테이블에 대해 하나의 커다란 UPDATE로하지 마십시오. 테이블을 부 풀릴 것입니다. – kgrittn

+0

가장 효과적이기 위해서는 각 배치 사이에 VACUUM이 필요합니다. – carbocation

관련 문제