Kim Seogyu
Database

대량 데이터 처리 시 Upsert 패턴 활용법

대량 쓰기에서 Upsert를 안전하고 빠르게 적용하는 기준을 정리합니다.

Published 2025년 12월 27일2 min read278 words

대량 데이터 처리 시 Upsert 패턴 활용법

Upsert란

Upsert는 "없으면 INSERT, 있으면 UPDATE"를 한 문장으로 처리하는 방식입니다. 핵심은 원자성경합 감소입니다.

왜 SELECT 후 INSERT/UPDATE보다 유리한가

기존 패턴:

SELECT 1 FROM users WHERE id = 1;
-- 없으면 INSERT, 있으면 UPDATE

문제점:

  • 왕복 쿼리 수 증가
  • SELECT 이후 경쟁 트랜잭션 개입 가능
  • 애플리케이션 분기 로직 복잡도 증가

Upsert는 이 분기를 DB 엔진으로 밀어 넣어 경합 구간을 줄입니다.

DB별 기본 문법

PostgreSQL

INSERT INTO users (id, name, email)
VALUES (1, 'Kim', 'kim@example.com')
ON CONFLICT (id) DO UPDATE
SET
  name = EXCLUDED.name,
  email = EXCLUDED.email,
  updated_at = NOW();

MySQL

INSERT INTO users (id, name, email)
VALUES (1, 'Kim', 'kim@example.com')
ON DUPLICATE KEY UPDATE
  name = VALUES(name),
  email = VALUES(email),
  updated_at = NOW();

배치 Upsert 패턴

INSERT INTO transactions (tx_id, amount, status)
VALUES
  ('tx_001', 100, 'pending'),
  ('tx_002', 200, 'confirmed'),
  ('tx_003', 150, 'pending')
ON CONFLICT (tx_id) DO UPDATE
SET
  amount = EXCLUDED.amount,
  status = EXCLUDED.status,
  updated_at = NOW();

설계 체크리스트

  • 고유키/유니크 인덱스가 명확한가.
  • UPDATE가 정말 필요한 컬럼만 갱신하는가.
  • 동일 데이터 재처리 시 결과가 동일한가(idempotency).
  • 배치 크기가 락 경합을 폭증시키지 않는가.

실수하기 쉬운 지점

  • 큰 TEXT/BLOB 컬럼까지 매번 갱신해서 쓰기 비용 급증.
  • 트리거나 CDC가 UPDATE 이벤트 폭증으로 병목.
  • 애플리케이션 타임스탬프와 DB 타임스탬프를 혼용해 정합성 깨짐.

운영 팁

  • 배치 크기부터 고정하고 성능 기준선을 먼저 잡습니다.
  • EXPLAIN (ANALYZE, BUFFERS)로 실제 경로를 확인합니다.
  • 실패 재시도는 "같은 입력이면 같은 결과"가 되도록 설계합니다.

요약

대량 인덱싱/동기화 작업에서 Upsert는 사실상 기본 선택입니다. 다만 성능은 문법이 아니라 인덱스 설계 + 배치 전략 + 갱신 컬럼 최소화로 결정됩니다.

Share

Related Articles

Comments

이 블로그는 제가 알고 있는 것들을 잊지 않기 위해 기록하는 공간입니다.
직접 작성한 글도 있고, AI의 도움을 받아 정리한 글도 있습니다.
정확하지 않은 내용이 있을 수 있으니 참고용으로 봐주세요.

© 2026 Seogyu Kim