blog

Postgre SQL - 초당 1000번 업데이트 발생 + 유니크 필드에 대한 정렬 전략

날짜: 2025-08-23

목록으로


아래는 초당 ~1,000건 sort_key 업데이트를 전제로, 단일 테이블 유지 vs 파티셔닝/캐시 분산 선택 기준과 실무 체크리스트입니다. (Django/DRF+AWS, Celery/Redis 전제)


0) 전제 모델(요약)


1) 결론 먼저: 선택 기준 요약

A. 단일 테이블로 계속 간다 (튜닝으로 충분)

B. 해시 파티셔닝으로 스케일아웃(DB 내 분산)

C. 캐시(예: Redis Sorted Set) + 비동기 동기화(읽기/쓰기 분리)


2) 단일 테이블로 버티는 조건—튜닝 체크리스트

  1. 스키마/인덱스
  1. 테이블/인덱스 저장 옵션
  1. 동시성 제어
  1. 모니터링 지표(주요)

위 조건 충족 시 초당 1,000 업데이트도 단일 테이블로 충분히 소화 가능합니다. 병목은 보통 “인덱스 과다”와 “autovacuum/체크포인트 튜닝 부재”에서 옵니다.


3) 파티셔닝이 필요한 신호와 방법

언제?

어떻게?

CREATE TABLE item_dyn_p (
  item_id BIGINT,
  list_id BIGINT,
  sort_key BIGINT,
  is_active BOOLEAN,
  updated_at TIMESTAMPTZ
) PARTITION BY HASH (list_id);

-- 16분할 예 (8~32 권장, 핫스팟/QPS에 맞춰 조절)
CREATE TABLE item_dyn_p0 PARTITION OF item_dyn_p FOR VALUES WITH (MODULUS 16, REMAINDER 0);
-- p1..p15 생략

-- 전파용 제약/인덱스
ALTER TABLE item_dyn_p ADD CONSTRAINT pk_item_dyn PRIMARY KEY (item_id);
CREATE UNIQUE INDEX ON item_dyn_p (list_id, sort_key);
CREATE INDEX ON item_dyn_p (list_id, sort_key DESC, item_id);

4) 캐시+비동기 동기화가 필요한 경우(읽기 SLA 우선)

패턴: “사용자 인터랙션성 재정렬이 많고, 읽기는 즉시 최신, DB는 최종적 일치(수초 지연 허용)”

장점: DB 부하 급감(특히 Sort/Top-N), 지연시간 안정 주의: 최종적 일관성 모델 설명 필요, 운영 복잡도↑


5) 의사결정 표 (현장용)

항목 단일 테이블 유지 해시 파티셔닝 캐시+비동기 동기화
p95 update 지연 ≤15–25ms 15–40ms 읽기 5–20ms(캐시), DB는 배치
DB CPU ≤60% 60–80% 40–60%(DB), 캐시에 이전
WAL rate ≤20–40MB/s 40–80MB/s DB는 완만, 캐시 I/O↑
운용 복잡도 낮음 중간 높음
일관성 강한 강한 최종적(수초)
확장성 한계 중간 높음 매우 높음

6) 실무 시행 순서(추천)

  1. 단일 테이블+튜닝으로 먼저 운영
  2. 핫스팟 뚜렷하면 HASH 파티셔닝(8→16→32 단계 확장)
  3. UX/읽기 지연이 더 엄격하면 캐시+배치 동기화 병행

7) Django/Celery 적용 포인트


한줄 요약


개선된 질문: “현재 p95 지연, DB CPU, WAL 속도, bloat, 재시도율(유니크 충돌) 지표를 기반으로 우리 트래픽에 맞는 ‘단일/파티셔닝/캐시’ 권고안을 수치로 제시해줄 수 있나요? pg_stat_statements/CloudWatch 지표 일부를 공유하겠습니다.”

추가로 할 수 있는 유용한 질문 2개:

  1. “Redis ZSET 기반 캐시-우선 구조에서 Celery 배치 upsert SQL과 충돌 재시도 로직(파라미터화) 예시를 보여줄 수 있나요?”
  2. “HASH 파티셔닝(16분할) 도입 시 마이그레이션 절차(다운타임 최소화/검증 체크리스트)를 단계별로 정리해줄 수 있나요?”

목록으로