Storage/RDBMS

RDBMS - Mysql Partitioning 파티셔닝

wave35 2025. 1. 19. 00:22

[ 개요 ]

MySQL Partitioning은 큰 테이블을 논리적으로 작은 단위(파티션)로 나누어 관리하는 기술입니다. 

테이블 데이터를 파티션 단위로 나누어 저장하여 데이터 처리 성능을 개선하고, 특정 쿼리를 최적화할 수 있습니다.

 

[ 장단점 ] 

장점

성능 향상 :

데이터가 파티션 단위로 분리되어 저장되므로 특정 파티션에만 접근하는 쿼리의 성능이 향상됩니다.

특히, 읽기 작업(SELECT)에 유리하며, 대규모 데이터에서 효율적입니다.

 

관리 용이성 :

특정 파티션만 드롭하거나 백업 및 복원할 수 있습니다.

 

병렬 처리 :

MySQL은 파티션을 병렬로 처리하므로, 대규모 데이터를 효과적으로 처리할 수 있습니다.

 

단점

제약 사항 :

외래 키(Foreign Key) 사용 불가합니다.

파티션 키가 반드시 Primary Key 또는 Unique Key에 포함되어야 합니다.

( Primary Key 또는 Unique Key가 없으면, 단순히 파티션 키를 기준으로 파티셔닝이 가능 )

 

추가 복잡성 :
설계 시 데이터 분포와 사용 패턴을 신중히 분석해야 하며, 부적절한 설계는 성능 저하를 초래할 수 있습니다.

 

쓰기 성능 저하 가능성 :

특정 파티션에 데이터가 몰리는 경우(스큐 데이터), 쓰기 작업의 성능이 저하될 수 있습니다.

파티션별로 병렬 처리가 되지만, 특정 파티션에 몰리면 병렬성이 저하됩니다.

또한 특정 파티션을 과도하게 쓰기 작업이 일어나면 락 경합(Lock Contention)이 일어납니다.

 

 

[ 사용 케이스 ]

  • 대규모 테이블에서 데이터가 시간이 지남에 따라 축적되는 경우: 로그 데이터
  • 시간 기반 데이터 관리: 특정 날짜 또는 기간별로 대규모 데이터를 자주 삭제하거나 관리해야 하는 경우
  • 스키마 구조가 안정적이고, 데이터 분포가 균일한 경우: 데이터를 적절히 분할하면 효율적

서비스에서 업데이트 트랜잭선 처리(OLTP)를 하고,

수백 GB ~ 수 TB까지의 중소 규모의 데이터이면 mysql partitioning을 적용하는게 효율적이고,

RBMS를 대체할 수 있거나 데이터 사이즈가 커지면 Hive, Spark(OLAP)를 사용하는 것이 좋습니다.

 

 

[ MySQL Partitioning 유형 ]

RANGE Partitioning

특정 열(column)의 값이 범위에 따라 데이터를 분할 합니다.

날짜, 숫자와 같이 순차적인 값이 있는 데이터를 활용합니다.

 

날짜 기반 파티션 분할 예제

CREATE TABLE logs (
  id INT NOT NULL,
  log_date DATE NOT NULL,
  message TEXT,
  PRIMARY KEY (id, log_date)
)
PARTITION BY RANGE (YEAR(log_date)) (
  PARTITION p2023 VALUES LESS THAN (2024),
  PARTITION p2024 VALUES LESS THAN (2025),
  PARTITION p_future VALUES LESS THAN MAXVALUE
);
log_date = '2023-06-15' → p2023에 저장.
log_date = '2024-03-10' → p2024에 저장.
log_date = '2025-01-01' → p_future에 저장.

 

LIST Partitioning

특정 열(column)의 값이 명신된 값 목록에 따라 데이터를 분할합니다.

지역, 카테고리, 상태코드 등 특정 값이 반복적으로 나타내는 경우 사용합니다.

 

지역 기반 파티션 예제

CREATE TABLE sales (
  id INT NOT NULL,
  region_code CHAR(2) NOT NULL,
  amount DECIMAL(10,2),
  PRIMARY KEY (id, region_code)
)
PARTITION BY LIST (region_code) (
  PARTITION p_asia VALUES IN ('KR', 'JP', 'CN'),
  PARTITION p_europe VALUES IN ('FR', 'DE', 'IT'),
  PARTITION p_others VALUES IN ('US', 'AU')
);
region_code = 'KR' → p_asia에 저장.
region_code = 'FR' → p_europe에 저장.
region_code = 'US' → p_others에 저장.

 

HASH Partitioning

해시 함수(Hash Funciton)을 사용하여 데이터를 균등하게 분할합니다.

데이터가 불균형하게 분포되었을 때나, 특정 범위가 없이 임의로 파티셔닝해야 할 때 사용합니다.

 

ID값으로 파티션 예제

CREATE TABLE logs (
  id INT NOT NULL,
  log_date DATE NOT NULL,
  message TEXT,
  PRIMARY KEY (id)
)
PARTITION BY HASH (id) PARTITIONS 4;
해시 함수로 id 값을 계산하여 4개의 파티션 중 하나에 저장.
예: id % 4 = 0 → 첫 번째 파티션에 저장.

 

 

[ 실행 속도 비교 ]

파티션을 적용할 때와 적용하지 않을 때의 쿼리 실행 속도를 비교해 보겠습니다.

단순히 SELECT - WHERE절의 경우 데이터 사이즈에 따라서 실행속도는 비슷할 수 있습니다.

 

아래는 비교시 사용한 쿼리입니다.

테이블은 no, member_id 라는 두개의 컬럼이 있고 no 기준으로 파티션을 지정하였습니다.

쿼리 내용은 동일한 테이블의 각각 다른 no에서, member_id의 교집합을 추출합니다.

 

파티션을 적용하지 않은 테이블에 실행한 쿼리

SELECT a.member_id
FROM user_member a
WHERE a.no = 2
  AND EXISTS (
    SELECT 1
    FROM user_member b
    WHERE b.no = 1
      AND b.member_id = a.member_id
  );

결과 : 약 5분

 

파티션을 적용한 테이블에 실행한 쿼리

SELECT a.member_id
FROM user_member PARTITION (p2) a
WHERE EXISTS (
    SELECT 1
    FROM user_member PARTITION (p1) b
    WHERE b.member_id = a.member_id
)

결과 : 약 1분

 

Explain으로 실행 계획을 확인