← 아티클 목록

MySQL 파티셔닝, 언제·어떻게 — 테이블 분할 기준과 함정

2026-12-07#database#MySQL#파티셔닝

테이블이 수억 행으로 불어나 단순 조회·삭제까지 느려지면 파티셔닝을 떠올립니다. 하지만 파티셔닝은 인덱스가 못 푸는 문제를 풀 때만 효과가 있고, 잘못 쓰면 오히려 느려집니다. 먼저 지금이 그 상황인지부터 판단합니다.

언제 쓰나 — 판단 기준

상황파티셔닝
인덱스로 해결되는 단건 조회불필요 (인덱스가 답)
날짜 범위로 대량 조회·집계RANGE 파티션 효과적
오래된 데이터를 주기적으로 삭제파티션 DROP이 압도적
행 수가 적은데 그냥 느림먼저 EXPLAIN부터

핵심은 오래된 데이터를 통째로 버리는 운영입니다. DELETE FROM logs WHERE created_at < ...는 수 시간 걸리고 락을 잡지만, 파티션 하나를 DROP하면 즉시 끝납니다.

RANGE 파티션 적용

월 단위로 로그를 나누는 예입니다. 파티션 키는 반드시 PK 또는 유니크 키에 포함돼야 합니다.

SQL
CREATE TABLE logs (
  id BIGINT NOT NULL AUTO_INCREMENT,
  created_at DATETIME NOT NULL,
  payload JSON,
  PRIMARY KEY (id, created_at)
) PARTITION BY RANGE (TO_DAYS(created_at)) (
  PARTITION p202610 VALUES LESS THAN (TO_DAYS('2026-11-01')),
  PARTITION p202611 VALUES LESS THAN (TO_DAYS('2026-12-01')),
  PARTITION pmax     VALUES LESS THAN MAXVALUE
);

오래된 달을 버릴 때:

SQL
ALTER TABLE logs DROP PARTITION p202610;   -- 즉시, 락 최소
ALTER TABLE logs REORGANIZE PARTITION pmax INTO (
  PARTITION p202701 VALUES LESS THAN (TO_DAYS('2027-02-01')),
  PARTITION pmax    VALUES LESS THAN MAXVALUE
);

프루닝이 되는지 확인

파티셔닝의 이득은 파티션 프루닝(필요한 파티션만 읽기)에서 나옵니다. 됐는지 EXPLAIN의 partitions 컬럼으로 확인합니다.

SQL
EXPLAIN SELECT * FROM logs WHERE created_at >= '2026-12-01';
OUTPUT
partitions: p202612      -- 한 파티션만 → 프루닝 성공
partitions: p202610,p202611,p202612,pmax   -- 전부 → 프루닝 실패

전부 다 찍히면 효과가 없는 겁니다. 흔한 원인:

  1. 파티션 키에 함수를 씌움WHERE YEAR(created_at)=2026은 프루닝 불가. 범위 조건(>=, <)으로 써야 합니다.
  2. WHERE에 파티션 키가 없음 — 다른 컬럼만으로 조회하면 모든 파티션을 스캔합니다.

적용 전 체크리스트

SQL
EXPLAIN SELECT ...;          -- partitions에 일부만 찍히는가
SHOW CREATE TABLE logs;      -- 파티션 정의·키 확인
-- PK/UNIQUE에 파티션 키 포함됐는가
-- 주요 조회가 파티션 키를 WHERE에 쓰는가

파티션 키를 안 쓰는 조회가 많다면 파티셔닝이 아니라 인덱스 설계 문제입니다.


파티션 프루닝을 EXPLAIN으로 직접 확인하고 RANGE 파티션을 설계하는 실습은 데이터베이스 트랙에서 회원가입 없이 무료로 할 수 있습니다.