빠른 비교
| 방식 | 기준 | 대표 사용 |
|---|---|---|
| Range partition | 날짜, 숫자 범위 | 월별 로그, 주문 |
| List partition | 명시 값 목록 | 지역, tenant, 상태 |
| Hash partition | hash 나머지 | 균등 분산 |
CREATE TABLE events (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
occurred_at TIMESTAMPTZ NOT NULL,
payload JSONB NOT NULL
) PARTITION BY RANGE (occurred_at);
CREATE TABLE events_2026_05
PARTITION OF events
FOR VALUES FROM ('2026-05-01') TO ('2026-06-01');구조
partitioning은 논리적으로 하나의 큰 테이블을 여러 물리 테이블로 나누는 방식입니다. 부모 테이블은 구조와 라우팅 기준을 정의하고, 실제 행은 조건에 맞는 partition에 저장됩니다.
events
├─ events_2026_05
├─ events_2026_06
└─ events_2026_07날짜 기준 로그처럼 오래된 데이터와 최신 데이터의 접근 패턴이 명확히 다르면 partition이 운영에 도움이 됩니다. 예를 들어 오래된 월 partition을 통째로 detach하거나 drop하면 대량 DELETE보다 훨씬 빠르고 vacuum 부담도 줄어듭니다.
Partition pruning
partition pruning은 쿼리 조건으로 읽을 필요 없는 partition을 제외하는 최적화입니다. 날짜 range partition에서 occurred_at 조건이 명확하면 해당 월 partition만 읽을 수 있습니다.
EXPLAIN
SELECT *
FROM events
WHERE occurred_at >= '2026-05-01'
AND occurred_at < '2026-06-01';쿼리 조건이 partition key와 맞지 않으면 pruning이 제대로 되지 않아 모든 partition을 훑을 수 있습니다. partition을 나누는 기준은 실제 WHERE 조건과 맞아야 합니다.
운영 기준
| 상황 | 판단 |
|---|---|
| 월별로 오래된 데이터 삭제 | range partition 적합 |
| tenant별 데이터 격리와 관리 | list partition 검토 |
| 특정 키 기준 균등 분산 | hash partition 검토 |
| 테이블이 작거나 쿼리가 단순 | 일반 테이블 유지 |
| partition key 없이 자주 조회 | partition 효과 제한 |
partition은 성능 기능이면서 운영 기능입니다. 모든 쿼리를 빠르게 만드는 마법이 아니라, 큰 테이블을 관리 가능한 조각으로 나누는 설계입니다.
주의할 점
partition 수가 지나치게 많으면 planning 비용과 운영 복잡도가 늘어납니다. 작은 partition을 과도하게 많이 만드는 설계는 오히려 느릴 수 있습니다.
partitioned table의 인덱스, 제약, foreign key, unique 조건은 일반 테이블과 제약이 다르게 느껴질 수 있습니다. 특히 unique 제약은 partition key 포함 여부를 먼저 확인해야 합니다.
참고 링크
1 sources