본문 바로가기
Database2026년 4월 15일4분 읽기

PostgreSQL 파티셔닝 실전 — 10억 행 테이블을 10배 빠르게 만드는 전략

YS
김영삼
조회 405

핵심 요약

파티셔닝은 거대 테이블을 쿼리 패턴에 맞는 작은 단위로 나눠 불필요한 스캔을 제거한다. 성능 이점의 대부분은 파티션 프루닝에서 나온다.

언제 파티셔닝을 해야 하나

  • 단일 테이블이 수천만 행 이상
  • 쿼리가 특정 범위·키에 집중
  • 오래된 데이터 대량 삭제가 필요 (DROP PARTITION이 DELETE보다 수천 배 빠름)
  • 인덱스 유지비용이 너무 큰 경우

파티셔닝 종류

RANGE (시계열 기본 선택)

CREATE TABLE events (
    id BIGSERIAL,
    created_at TIMESTAMPTZ NOT NULL,
    payload JSONB
) PARTITION BY RANGE (created_at);

CREATE TABLE events_2026_04 PARTITION OF events
  FOR VALUES FROM ('2026-04-01') TO ('2026-05-01');

LIST (카테고리)

CREATE TABLE orders (region TEXT, ...) PARTITION BY LIST (region);
CREATE TABLE orders_kr PARTITION OF orders FOR VALUES IN ('KR');
CREATE TABLE orders_us PARTITION OF orders FOR VALUES IN ('US');

HASH (균등 분산)

CREATE TABLE sessions (user_id BIGINT, ...) PARTITION BY HASH (user_id);
CREATE TABLE sessions_0 PARTITION OF sessions FOR VALUES WITH (MODULUS 8, REMAINDER 0);

파티션 프루닝 확인

EXPLAIN (ANALYZE, BUFFERS)
SELECT count(*) FROM events
 WHERE created_at >= '2026-04-10' AND created_at < '2026-04-11';

계획에 Partitions removed by partitioning: N이 보이면 정상.

자동 파티션 관리

pg_partman을 쓰면 월/일 단위 파티션이 자동 생성·폐기된다.

CREATE EXTENSION pg_partman;
SELECT partman.create_parent(
  'public.events', 'created_at', 'range', 'monthly',
  p_premake := 6
);

인덱스 전략

  • 부모 테이블에 선언하면 모든 파티션에 자동 전파
  • UNIQUE/PK는 파티션 키 포함 필수
  • 핫 파티션만 BRIN 대신 B-Tree 고려 (쿼리 패턴별)

데이터 이관 시나리오

  1. 새 파티션 테이블 생성 (구 테이블과 동일 스키마)
  2. INSERT INTO new_partition SELECT ... FROM old_table WHERE ...
  3. 앱 쓰기를 트리거/듀얼 라이트로 전환
  4. 이관 완료 후 ATTACH PARTITION으로 통합
  5. 구 테이블 rename → drop

실무 함정

  • 기본 파티션(DEFAULT) 없이 삽입 시 실패 → 항상 생성
  • COPY는 파티션별로 라우팅되지만 대량 COPY는 lock 경합
  • 파티션 1000개 이상은 플래너 비용 급증 → 계층 파티셔닝 고려

자주 묻는 질문

샤딩과 파티셔닝 차이?

파티셔닝은 단일 DB 내 논리 분할. 샤딩은 여러 DB/노드 분산. 먼저 파티셔닝으로 해결되면 그 선에서 끝내는 것이 운영 비용상 유리.

파티션 수 상한?

수백 개까지 무난, 천 단위부터 플래너 overhead 체감. 큰 경우 LIST-of-RANGE 계층 파티셔닝.

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록