대용량 MySQL 테이블을 Range/List/Hash/Key 방식으로 나눠 쿼리가 필요한 파티션만 읽게 만드는 기법입니다.
파티셔닝의 정의
파티셔닝은 데이터베이스 테이블을 여러 작은 부분으로 나누는 기법입니다. 데이터를 효율적으로 관리하고 성능을 개선하는 데 사용합니다.
테이블이 커지면 데이터 접근 속도가 느려집니다. 파티셔닝을 적용하면 쿼리 실행 시 필요한 파티션만 검색하여 성능을 높일 수 있습니다.
파티셔닝의 주요 이점
파티셔닝은 특정 파티션만 읽어 검색 속도를 높입니다. 파티션 단위로 백업·복구·아카이빙을 처리할 수 있어 관리도 쉬워집니다. 파티션별로 독립적인 처리가 가능하므로 병렬 작업도 할 수 있습니다.
실무에서 파티셔닝을 도입하는 주된 이유는 성능과 관리 용이성입니다. 병렬 처리의 효과는 워크로드에 따라 달라집니다.
MySQL 파티셔닝 방식
Range Partitioning (범위 파티셔닝)
Range 파티셔닝은 날짜, 숫자 등 연속적인 값으로 데이터를 분할합니다.
Range 파티셔닝은 PARTITION BY RANGE 절에 지정한 표현식의 값 범위에 따라 행을 분배합니다. VALUES LESS THAN은 각 파티션이 수용하는 값의 상한을 정의합니다.
CREATE TABLE orders (
order_id INT,
order_date DATE,
customer_id INT,
amount DECIMAL(10, 2)
)
PARTITION BY RANGE (YEAR(order_date)) (
PARTITION p0 VALUES LESS THAN (2021),
PARTITION p1 VALUES LESS THAN (2022),
PARTITION p2 VALUES LESS THAN (2023),
PARTITION p3 VALUES LESS THAN (2024)
);장점: 날짜 범위 조회 시 해당 파티션만 검색 단점: 데이터 분포가 고르지 않으면 특정 파티션에 몰림
YEAR() 같은 함수로 파티셔닝하면 파티셔닝 컬럼이 모든 프라이머리 키와 유니크 키에 포함돼야 합니다. RANGE COLUMNS(order_date)는 컬럼 값을 그대로 비교하여 이 제약을 피합니다. 날짜 범위 조회에서는 파티션 가지치기도 더 안정적으로 동작합니다.
List Partitioning (목록 파티셔닝)
List 파티셔닝은 지정된 값 목록에 따라 데이터를 분할합니다. 국가 코드, 지역, 상태 값 등에 적합합니다. VALUES IN은 각 파티션에 매핑할 값의 목록을 정의합니다.
CREATE TABLE customers (
customer_id INT,
customer_name VARCHAR(50),
country_code CHAR(2)
)
PARTITION BY LIST (country_code) (
PARTITION p_us VALUES IN ('US'),
PARTITION p_uk VALUES IN ('UK'),
PARTITION p_ca VALUES IN ('CA')
);Hash Partitioning (해시 파티셔닝)
Hash 파티셔닝은 해시 함수를 사용하여 데이터를 균등하게 분산합니다. PARTITIONS 4는 만들 파티션 개수를 지정합니다. MySQL은 해시 값으로 행을 4개 파티션에 나눕니다.
CREATE TABLE transactions (
transaction_id INT,
customer_id INT,
amount DECIMAL(10, 2)
)
PARTITION BY HASH (customer_id) PARTITIONS 4;장점: 데이터 균등 분산, 특정 파티션 과부하 방지 단점: 범위 쿼리 최적화 어려움
Key Partitioning (키 파티셔닝)
Key 파티셔닝은 MySQL 내부 해시 알고리즘을 사용합니다. 프라이머리 키나 유니크 키를 기준으로 데이터를 분할합니다. PARTITION BY KEY(컬럼)은 분할 기준 컬럼을, PARTITIONS n은 파티션 개수를 지정합니다.
CREATE TABLE logs (
log_id INT AUTO_INCREMENT,
log_message VARCHAR(255)
)
PARTITION BY KEY(log_id) PARTITIONS 4;파티션 관리
파티션 추가
ALTER TABLE orders ADD PARTITION (
PARTITION p4 VALUES LESS THAN (2025)
);파티션 삭제
ALTER TABLE orders DROP PARTITION p0;파티셔닝 최적화 팁
flowchart LR
Q[WHERE 조건] --> P{파티션 범위를<br/>계산할 수 있는가}
P -->|예| S[해당 파티션만 스캔]
P -->|아니요| A[모든 파티션 검사]
Partition Pruning 활용
Partition Pruning은 쿼리가 불필요한 파티션을 건너뛰는 동작입니다. 쿼리 시 WHERE 조건에 파티셔닝 컬럼을 포함하면 MySQL이 필요한 파티션만 검색합니다.
-- 좋은 예: p2 파티션만 검색
SELECT * FROM orders WHERE order_date BETWEEN '2022-01-01' AND '2022-12-31';
-- 나쁜 예: 모든 파티션 검색
SELECT * FROM orders WHERE amount > 1000;적합한 테이블 선택
- 적합: 수백만 행 이상의 대용량 테이블
- 부적합: 작은 테이블 (관리 복잡성만 증가)
파티셔닝의 한계
| 제한 사항 | 설명 |
|---|---|
| 복잡성 증가 | 설계와 관리가 복잡해짐 |
| FOREIGN KEY(FK) 제약 | FOREIGN KEY 지원 제한 |
| 데이터 이동 | 파티션 간 이동 시 오버헤드 발생 |
정리
파티셔닝은 큰 테이블을 나눠 필요한 파티션만 읽게 합니다. 날짜 범위 조회에는 Range, 정해진 범주에는 List가 맞습니다. Hash와 Key는 행을 여러 파티션에 분산합니다.
Partition Pruning은 조건에서 파티션 범위를 계산할 수 있을 때 동작합니다. 테이블 크기만으로 도입을 결정하면 관리 비용만 늘 수 있습니다. 실제 쿼리 계획과 파티션별 데이터 분포를 먼저 측정해야 합니다.
| 방식 | 적합한 상황 |
|---|---|
| Range | 날짜/시간 기반 조회가 많을 때 |
| List | 카테고리/지역별 분류 시 |
| Hash | 균등 분산이 필요할 때 |
| Key | PK 기반 자동 분산 |