PostgreSQL · 2026-03-25

PostgreSQL 대규모 데이터 로딩: 병렬 COPY

대량 데이터를 빠르게 적재하는 병렬 COPY 전략과 설정, 파일 분할·세션 병렬화·성능 튜닝을 포함한 실무 중심의 최적화 전략

작성일 : 2026-03-25 ㆍ 작성자 : 관리자
post
목차

개요

대규모 데이터 적재는 단일 COPY로는 한계가 있다. 병렬 COPY를 적용하면 전체 로드 시간을 크게 줄일 수 있다. 이 글은 초보자도 이해할 수 있도록 병렬 COPY 개념, 준비, 실행 방법과 성능 고려사항을 단계적으로 설명한다.

병렬 COPY의 개념

왜 병렬 COPY인가

단일 세션의 COPY는 I/O, CPU, WAL 쓰기 병목에 걸린다. 파일을 여러 조각으로 나누어 여러 세션에서 동시에 COPY하면 자원 활용률이 올라간다. 특히 다중 코어와 빠른 디스크가 있을 때 효과가 크다.

기본 원리와 전제 조건

전제 조건

  • 충분한 디스크 I/O 대역폭
  • 여러 클라이언트 세션을 허용하는 설정 (max_connections)
  • 테이블 구조와 인덱스, FK 상태 파악

COPY 명령 기본 예

COPY schema.table (col1, col2, col3) FROM '/path/data.csv' WITH (FORMAT csv, HEADER true);

병렬 전략 분류

파일 분할 후 병렬 COPY

가장 일반적인 방법은 원본 파일을 여러 조각으로 나눈 뒤 각 파일을 별도 세션에서 COPY 하는 것이다. 파일 분할은 OS 툴로 간단히 처리한다.

파일 분할 예

split -l 1000000 large.csv part_  # 100만 행 단위로 분할
# 또는 GNU parallel과 조합
ls part_* | parallel -j 8 "psql -d mydb -c \"COPY myschema.mytable FROM '{}' WITH (FORMAT csv)\""

위 예는 각 분할 파일을 8개 병렬 작업으로 적재한다. psql 명령 내부의 쌍따옴표·연속 인용에 유의한다.

파티셔닝을 이용한 병렬 적재

데이터 특성이 분할 키와 맞으면 파티션을 미리 생성한 뒤 각 파티션에 병렬로 LOAD 하면 효과적이다. 파티션별로 인덱스와 통계를 따로 관리할 수 있어 추후 쿼리 성능에도 유리하다.

성능 고려사항

WAL과 동기화

기본 COPY는 WAL을 발생시킨다. 대량 로딩 시 WAL 쓰기가 병목이 될 수 있다. 아래 설정 조합을 고려한다.

-- 트랜잭션 단위로 묶어서 COMMIT 빈도 줄이기
BEGIN; COPY ... ; COMMIT;

-- 세션별로 설정 변경 (주의: 데이터 안전성 영향)
SET synchronous_commit = off;
SET maintenance_work_mem = '1GB';

인덱스와 제약조건

인덱스가 많으면 INSERT 비용이 커진다. 대량 로딩 전에는 인덱스를 제거하거나 비활성화하고, 로딩 후 재생성하는 것이 유리하다. FK 검사는 로드 후 검증으로 미루면 속도 향상.

checkpoint와 autovacuum

대량 적재 중 잦은 체크포인트는 성능 저하로 이어진다. checkpoint_segments (또는 현재 버전의 checkpoint_timeout/target) 설정을 조정해 대량 적재 동안 체크포인트 발생을 분산시키는 것을 고려한다. 적재 후 VACUUM을 실행하여 통계를 갱신한다.

구체적 실행 흐름 (단계별)

1. 준비

  • 스키마 확인 및 불필요 인덱스 제거
  • 테이블을 파티션으로 나눌지 결정
  • 로드 파일을 크기와 로드 세션 수에 맞게 분할

2. 설정 튜닝

-- 세션 단위 권장 조정 예
SET synchronous_commit = off;
SET work_mem = '64MB';
SET maintenance_work_mem = '512MB';

3. 병렬 실행

각 분할 파일을 별도 psql 세션에서 COPY로 적재한다. GNU parallel, xargs -P, 또는 커스텀 스크립트를 사용해 병렬화한다.

4. 마무리

  • 인덱스 재생성 및 통계 수집 (ANALYZE)
  • 필요 시 WAL 동기화 설정 복원
  • 성능 검증과 모니터링 로그 확인

실전 예제

간단한 쉘 스크립트로 병렬 LOAD를 수행하는 예시다. 파일이 part_aa, part_ab ... 형태로 분할된 상태를 가정한다.

for f in part_*; do
  echo "COPY 시작: $f"
  psql -d mydb -c "COPY myschema.mytable FROM '$PWD/$f' WITH (FORMAT csv)" &
  # 백그라운드로 실행
  # 병렬수 제어는 프로세스 카운트 체크로 구현 가능
  while [ $(jobs -r | wc -l) -ge 8 ]; do sleep 1; done
done
wait

모범 사례 요약

  • 파일을 잘게 쪼개고 서버 코어 수와 디스크 I/O를 고려해 병렬 수 결정
  • 로드 전 불필요 인덱스·제약을 제거하고, 후처리로 복원
  • WAL·checkpoint 영향 이해 후 세션/인스턴스 설정 조정
  • 파티셔닝을 활용하면 장기적으로 관리와 쿼리 성능이 유리
  • 작업 전후에 모니터링을 통해 병목 요소를 식별

마무리

병렬 COPY는 대량 입력 postgres 최적화에서 핵심 전략이다. 적절한 파일 분할, 세션 설정, 인덱스 관리와 모니터링을 조합하면 bulk load postgres 성능이 크게 향상된다. 환경과 요구사항에 맞춰 실험하면서 최적의 병렬 copy postgres 방법을 찾는 것이 중요하다.

병렬 copy postgres 방법 bulk load postgres 성능 대량 입력 postgres 최적화 postgres copy 병렬 postgres 성능 튜닝 COPY 파일 분할 데이터 로딩 최적화 파티셔닝 병렬 로드