가정
Q에 정보가 없기 때문에 다음과 같이 가정합니다.
- 데이터는 데이터베이스 서버의 파일에서 가져옵니다.
- 데이터는 목표 테이블과 일치하도록 행당 고유 한
COPY
출력 과 같이 형식이 지정 됩니다.
그렇지 않은 경우 먼저 형식을 올바르게 지정하거나 옵션을 사용 하여 형식을 처리하십시오. id
COPY
- 목표 테이블 또는 대부분의 행에서 모든 단일 행을 갱신하고 있습니다.
- 대상 테이블을 삭제하고 다시 만들 수 있습니다.
이는 동시 액세스가 없음을 의미 합니다. 그렇지 않으면이 관련 답변을 고려하십시오.
- 인덱스를 제외하고는 종속 개체가 전혀 없습니다.
해결책
세 번째 글 머리 기호 의 링크에 설명 된 것과 비슷한 방법으로 접근하는 것이 좋습니다 . 주요 최적화
임시 테이블을 만들려면 더 간단하고 빠른 방법이 있습니다.
CREATE TEMP TABLE tmp_tbl AS SELECT * FROM tbl LIMIT 0;
데이터베이스 내부 의 UPDATE
임시 테이블에서 하나의 빅 데이터가 데이터베이스 외부에서 개별 업데이트보다 몇 배 빠릅니다.
에서 의 PostgreSQL의 MVCC 모델 , UPDATE
수단은 새 행 버전을 생성하고 삭제 된 것으로 이전을 표시합니다. 그 비용 INSERT
은 DELETE
합산 된 것만큼이나 비쌉니다 . 또한 죽은 튜플이 많이 남습니다. 어쨌든 전체 테이블을 업데이트하기 때문에 새 테이블을 만들고 이전 테이블을 삭제하는 것이 전체적으로 더 빠릅니다.
경우 당신이 충분한 RAM, 세트가 temp_buffers
RAM에 임시 테이블을 보유 할만큼 충분히 높은 (전용이 세션에!) - 다른 작업을 수행하기 전에.
필요한 RAM의 양을 추정하려면 작은 샘플로 테스트를 실행하고 db object size 함수를 사용 하십시오 .
SELECT pg_size_pretty(pg_relation_size('tmp_tbl')); -- complete size of table
SELECT pg_column_size(t) FROM tmp_tbl t LIMIT 10; -- size of sample rows
완전한 스크립트
SET temp_buffers = '1GB'; -- example value
CREATE TEMP TABLE tmp_tbl AS SELECT * FROM tbl LIMIT 0;
COPY tmp_tbl FROM '/absolute/path/to/file';
CREATE TABLE tbl_new AS
SELECT t.col1, t.col2, u.field1, u.field2
FROM tbl t
JOIN tmp_tbl u USING (id);
-- Create indexes like in original table
ALTER TABLE tbl_new ADD PRIMARY KEY ...;
CREATE INDEX ... ON tbl_new (...);
CREATE INDEX ... ON tbl_new (...);
-- exclusive lock on tbl for a very brief time window!
DROP TABLE tbl;
ALTER TABLE tbl_new RENAME TO tbl;
DROP TABLE tmp_tbl; -- will also be dropped at end of session automatically
동시 부하
테이블의 동시 작업 (시작시 가정에서 배제한)은 테이블이 끝 근처에서 잠기고 트랜잭션이 커밋 되 자마자 실패하면 테이블 이름이 즉시 OID로 확인되기 때문에 대기하지만 새 테이블의 OID가 다릅니다. 테이블은 일관성을 유지하지만 동시 작업에는 예외가 발생하여 반복해야합니다. 이 관련 답변의 세부 사항 :
업데이트 경로
UPDATE
경로를 이동 해야하는 경우 업데이트 중에 필요하지 않은 인덱스를 삭제하고 나중에 다시 만드십시오. 모든 개별 행에 대해 인덱스를 업데이트하는 것보다 한 조각으로 인덱스를 만드는 것이 훨씬 저렴합니다. 이것은 또한 HOT 업데이 트를 허용 할 수 있습니다 .
내가 사용하여 유사한 절차를 설명 UPDATE
에 SO에이 밀접하게 관련 대답 .