피드로 돌아가기
Como importei 55 milhões de empresas para PostgreSQL em menos de 3 horas
Dev.toDev.to
Database

COPY와 Temp Table 기반 PostgreSQL 벌크 로드 최적화로 5,500만 건 임포트 12시간에서 3시간 미만으로 단축

Como importei 55 milhões de empresas para PostgreSQL em menos de 3 horas

Pedro Parker2026년 4월 17일6intermediate

Context

브라질 기업 데이터 5,500만 건을 매월 업데이트해야 하는 환경에서 ORM 기반의 INSERT 방식 사용 시 12시간 이상의 과도한 소요 시간 발생. ORM의 객체 오버헤드와 PostgreSQL의 개별 쿼리 파싱 및 실행 계획 생성으로 인한 병목 지점 확인.

Technical Solution

  • SQL Parser와 Planner를 우회하여 Heap 영역에 직접 데이터를 쓰는 PostgreSQL 전용 COPY 메커니즘 채택
  • COPY의 ON CONFLICT 미지원 한계 극복을 위해 Temp Table에 우선 로드 후 실제 테이블로 UPSERT 수행하는 2단계 전략 설계
  • 데이터 로드 중 B-tree/GIN 인덱스 업데이트 비용 제거를 위해 Index Drop 후 로드 완료 시점에 CREATE INDEX CONCURRENTLY로 재구성
  • WAL 플러시 대기 시간을 제거하는 synchronous_commit = off 설정과 work_mem 확장을 통한 쓰기 성능 최적화
  • 독립적인 ZIP 파일 구조를 활용한 ThreadPoolExecutor 기반의 병렬 다운로드 및 임포트 파이프라인 구축
  • 트랜잭션 오버헤드와 메모리 사용량의 균형점을 고려한 200K 단위의 최적 Batch Size 설정

- PostgreSQL 벌크 로드 시 INSERT 대신 COPY 명령어 우선 검토 - 대량 적재 전 인덱스를 제거하고 적재 후 재생성하는 워크플로우 적용 - Upsert 필요 시 Temp Table을 브릿지로 활용하는 패턴 도입 - 데이터 유실 리스크가 낮은 초기 적재 시 `synchronous_commit = off` 설정 검토

원문 읽기