MySQL 파티셔닝 가이드
Range, List, Hash, Key 파티셔닝으로 대용량 MySQL 테이블 성능을 최적화하는 전략
Contents
대용량 MySQL 테이블을 Range/List/Hash/Key 방식으로 나눠 쿼리가 필요한 파티션만 읽게 만드는 기법이다.
파티셔닝의 정의
파티셔닝은 데이터베이스 테이블을 여러 작은 부분으로 나누어 데이터를 효율적으로 관리하고 성능을 개선하는 기법이다.
테이블이 커지면 데이터 접근 속도가 느려지는데, 파티셔닝을 적용하면 쿼리 실행 시 전체 테이블이 아닌 필요한 파티션만 검색하여 성능을 높일 수 있다.
파티셔닝의 주요 이점
- 성능 향상: 특정 파티션만 읽어 검색 속도 향상
- 관리 용이성: 파티션 단위로 백업, 복구, 아카이빙 가능
- 병렬 처리: 파티션별 독립적 처리로 병렬 작업 가능
실무에서 파티셔닝을 도입하는 주된 이유는 성능과 관리 용이성이다. 병렬 처리는 워크로드에 따라 효과가 갈린다.
MySQL 파티셔닝 방식
Range Partitioning (범위 파티셔닝)
날짜, 숫자 등 연속적인 값으로 데이터를 분할한다.
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 (목록 파티셔닝)
지정된 값 목록에 따라 분할한다. 국가 코드, 지역, 상태 값 등에 적합하다. 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 (해시 파티셔닝)
해시 함수를 사용하여 데이터를 균등하게 분산한다. 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 (키 파티셔닝)
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;파티셔닝 최적화 팁
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이 동작하려면 WHERE 조건에 파티셔닝 컬럼이 들어가야 한다. 수백만 행 미만의 작은 테이블이나 FOREIGN KEY 의존이 강한 스키마는 파티셔닝의 이점보다 관리 복잡성이 커지므로 적용 전에 따져봐야 한다.
| 방식 | 적합한 상황 |
|---|---|
| Range | 날짜/시간 기반 조회가 많을 때 |
| List | 카테고리/지역별 분류 시 |
| Hash | 균등 분산이 필요할 때 |
| Key | PK 기반 자동 분산 |