MySQL에서 대용량 테이블을 파티셔닝할 때, 조건이 정확한 특정 값 목록으로 나뉘는 경우가 있다.
이럴 때 사용하는 전략이 바로 LIST 파티셔닝이다.
RANGE 파티션이 범위 기반이라면 LIST는 딱 정해진 값들에 대해 명시적으로 분할하는 구조다.
예를 들어 국가 코드, 지역 코드, 업무 구분 코드처럼 딱 정해진 값들로 쿼리가 자주 분리될 경우에 효과적이다.

✅ LIST 파티션이란?
LIST 파티션은 지정한 컬럼 값이 미리 정의된 목록 중 어떤 값인지에 따라 데이터를 다른 파티션에 저장한다.
구조는 간단하지만 실제로는 매우 강력하다. 특히 범위가 아닌 고정된 분류값에 최적화되어 있다.
예를 들어 다음과 같은 분류가 있다고 가정해보자.
- 업무 코드: 1 = 일반, 2 = 관리자, 3 = 운영자, 4 = 파견
- 지역 코드: 11 = 서울, 26 = 부산, 41 = 경기, 43 = 충북
이런 값은 LIST 파티션으로 효율적으로 나눌 수 있다.
🧪 실무 예제: 지역 코드 기준 LIST 파티션 나누기
다음은 user_logs 테이블을 지역 코드 region_code 기준으로 분할하는 예제다.
CREATE TABLE user_logs (
id BIGINT NOT NULL,
region_code INT NOT NULL,
log_date DATE NOT NULL,
activity TEXT,
PRIMARY KEY (id, region_code)
)
PARTITION BY LIST (region_code) (
PARTITION p_seoul VALUES IN (11),
PARTITION p_busan VALUES IN (26),
PARTITION p_gyeonggi VALUES IN (41),
PARTITION p_chungbuk VALUES IN (43),
PARTITION p_etc VALUES IN (DEFAULT)
);
이 테이블은 다음과 같이 동작한다.
- region_code = 11이면 p_seoul에 저장
- region_code = 26이면 p_busan에 저장
- region_code = 41이면 p_gyeonggi에 저장
- region_code = 43이면 p_chungbuk에 저장
- 나머지 값은 p_etc로 처리할 수 있다 (DEFAULT는 MySQL에서 직접 지원하진 않지만, 범위에 없는 값을 나중에 추가하거나 CASE로 우회 가능)
📋 WHERE 절 최적화와 Partition Pruning
LIST 파티션은 WHERE 절이 파티션 키와 직접 연결된 경우에만 Partition Pruning이 가능하다.
즉, 다음과 같은 쿼리는 해당 파티션만 접근한다.
SELECT * FROM user_logs
WHERE region_code = 26;
이 쿼리는 p_busan만 조회하므로 성능이 극대화된다.
반면 region_code IN (26, 41)은 두 개 파티션을 조회하며
region_code >= 20처럼 범위 조건은 LIST 파티션에서는 제대로 프루닝되지 않는다.
따라서 LIST 파티션은 WHERE 절에 = 또는 IN 조건이 자주 쓰이는 테이블에 적합하다.
⚠️ 주의할 점과 한계
- 파티션 값 중복 불가: 두 개 이상의 파티션에 같은 값이 있으면 오류
- NULL 값 허용되지 않음: NULL은 별도로 처리하지 않으면 삽입 실패
- 모든 값에 대해 파티션 정의가 되어 있어야 함: 누락 시 INSERT 오류 발생
- 외래키, FULLTEXT 인덱스 불가: 파티션 테이블 전체 제한사항 적용됨
- 조건 변경 시 ALTER TABLE로 재정의 필요: 실시간 추가 어려움
이러한 제약 때문에, LIST 파티션을 설계할 때는 가능한 모든 케이스를 미리 정의해두는 것이 중요하다.
🔍 LIST vs RANGE 차이 비교
| 항목 | LIST 파티션 | RANGE 파티션 |
| 분할 기준 | 고정된 값 목록 | 연속된 수치 또는 날짜 범위 |
| WHERE 절 최적화 | =, IN 조건에서 효과적 | BETWEEN, >=, <= 조건에 효과적 |
| 주 사용 케이스 | 코드 테이블, 구분자 필드 등 | 날짜 로그, 숫자 구간 분할 |
| 설계 난이도 | 값 명시 필요 → 비교적 높음 | 범위만 설정 → 상대적으로 간단함 |
즉, 리스트형 데이터(코드성 데이터)를 정리하기에 매우 효과적이며,
날짜나 범위 조건과는 궁합이 맞지 않는다.
🧠 실무 활용 예시
- 회원 등급에 따른 리스트 분할
- BASIC, SILVER, GOLD, VIP → 각 등급별 파티션
- 카테고리 코드 기반 게시글 분할
- 카테고리별 글 수가 많은 경우 I/O 분산
- 국가 코드 기반 사용자 접속 로그 분할
- 대륙이나 국가 그룹별 분석을 빠르게 할 수 있음
- 업무 구분 코드 기반 처리 이력 분할
- 업무 시스템에서 분리된 처리 로직 최적화 가능
이처럼 LIST 파티션은 실무에서 다양하게 활용되며, 특히 데이터가 정형화된 시스템에서 빛을 발한다.
🔧 삽질 방지 실전 팁
- 파티션 키에 NULL이 들어가는지 꼭 체크
- INSERT 시 알 수 없는 코드 값이 들어올 가능성 대비
- 사용자가 입력하는 코드 값을 파티션 설계에 포함시키지 말 것
- 모든 코드를 미리 정의하기 어렵다면 RANGE 또는 HASH 고려
- 리스트가 너무 많을 경우, 쿼리가 복잡해지므로 관리 포인트 늘어남
✅ 정리
- LIST 파티션은 코드값 같은 고정된 목록형 데이터에 적합한 파티셔닝 방식이다.
- 조건이 명확할수록 프루닝 효과가 커지며, I/O 성능이 극적으로 향상된다.
- 단, 누락된 값에 대한 처리를 고려하지 않으면 INSERT 실패나 장애로 이어질 수 있다.
- 설계 시 모든 가능성 있는 값들을 파악하고, 예외 케이스를 포함하도록 주의해야 한다.
🔗 공식 문서 참고
MySQL 8.0 Reference Manual - LIST Partitioning
'DB' 카테고리의 다른 글
| [MySQL] 대용량 테이블 분할 실전 사례와 쿼리 튜닝 효과 (1) | 2025.07.09 |
|---|---|
| [MySQL] 파티션 설계 시 주의할 점과 실무 적용 팁 🚨 (2) | 2025.07.09 |
| [MySQL] KEY 파티션 전략: 자동 해시로 분산 처리하기 🔑 (1) | 2025.07.09 |
| [MySQL] HASH 파티션 전략: 균등 분산의 핵심 알고리즘 ⚙️ (1) | 2025.07.08 |
| [MySQL] RANGE 파티션 전략: 날짜 기반 분할 실무 예제 📆 (2) | 2025.07.08 |
| [MySQL] 파티셔닝(Partitioning) 개념과 사용 목적 총정리 📦 (0) | 2025.07.08 |
| [MySQL] 쿼리 리팩토링 전/후 실행계획으로 성능 변화 분석하기 🔍 (0) | 2025.07.08 |
| [MySQL] 복잡한 쿼리 리팩토링: 서브쿼리 → JOIN → CTE 변환 사례 분석 (0) | 2025.07.08 |