파티셔닝은 테이블과 인덱스 데이터를 파티션 단위로 나누어 저장하는 것을 말한다
테이블을 파티셔닝하면 하나의 테이블일지라도 파티션 키에 따라 물리적으로는 별도의 세그먼트에 데이터가 저장되며, 인덱스도 마찬가지다.
파티셔닝이 왜 필요한가?
테이블을 적당한 단위로 나누어 저장한다면 Full Scan 하더라도 일부 파티션 세그먼트만 읽고 멈출출 수 있다. 또한 파티셔닝과 병렬 처리가 만났을 때 그 효과가 배가된다.
파티셔닝도 클러스터, IOT와 마찬가지로 관련 있는 데이터가 흩어지지 않고 물리적으로 인접하도록 저장하는 클러스터링 기술에 속한다.
클러스터와 다른 점은 세그먼트 단위로 모아서 저장한다.
파티션 테이블
create table partition_table
partition by range(deptno) (
partition p1 values less than (20)
, partition p2 values less than (30)
, partition p3 values less than (40)
)
as
select * from emp ;
create index ptable_empno_idx on partition_table(empno) LOCAL;
파티셔닝은, 내부에 몇 개의 세그먼트를 생성하고 그것들이 논리적으로 하나의 오브젝트임을 메타 정보로 딕셔너리에 저장해 두는 것에 지나지 않는다.
파티션 테이블은 테이블과 세그먼트 관계가 1:M 관계다.
create table 주문 (주문번호 number, 주문일자 varchar(2), 고객id ... )
partition by range (주문일자) (
partition p2009_q1 values less than ('20090401')
, partition p2009_q2 values less than ('20090701')
, partition p2009_q3 values less than ('20091001')
, partition p2009_q4 values less than ('20100101')
.....
, partition p9999_mx values less than (MAXVALUE)
);
파티셔닝 테이블에 값을 입력하면 각 레코드를 파티션 키 컬럼 값에 따라 분할 저장하고, 읽을 때도 검색 조건을 만족하는 파티션만 읽을 수 있어 이력성 데이터 조회 시 성능을 크게 향상 시켜준다.
파티션 키에 해시 함수를 적용한 결과 값이 같은 레코드를 같은 세그먼트에 저장해 두는 방식이며, 주로 고객ID 처럼 변별력이 좋고 데이터 분포가 고른 컬럼을 파티션 기준 컬럼으로 선정해야 효과적이다.
해시 알고리즘 특성상 등치(=) 조건 또는 IN-List 조건으로 검색할 때만 파티션 Pruning이 작동한다.
create table 고객 (고객id varchar2(5), 고객명 varchar2(10), ...)
partition by hash(고객id) partitions 4;
데이터가 모든 파티션에 고르게 분산돼 있다면, 각 파티션이 서로 다른 디바이스에 저장돼 있다면 병렬 I/O 성능을 극대화 할 수 있다.
동시 입력이 많은 대용량 테이블이나 인덱스에 발생하는 경합을 줄일 목적으로도 해시 파티셔닝을 사용한다. 대용량 거래 테이블일수록 DML 발생량이 많이 경합 발생 가능성도 그만큼 크다.
이럴 때 테이블을 해시 파티셔닝하면 세그먼트 헤더 블록에 대한 경합을 줄일 수 있다.
사용자에 의해 미리 정해진 그룹핑 기준에 따라 데이터를 분할 저장하는 방식이다.
create table 인터넷매물 (물건코드 varchar2(5), 지역분류 varchar2(4), ...)
partition by list(지역분류) (
partition p_지역1 values ('서울')
, partition p_지역2 values ('경기', '인천')
, ...
, partition p_기타 values (DEFAULT) -> 기타 지역
);
리스트 파티셔닝은 단일 컬럼으로만 파티션 키를 지정할 수 있다.
결합 파티셔닝을 구성하면 서브 파티션마다 세그먼트를 하나씩 할당하고, 서브 파티션 단위로 데이터를 저장한다.
즉, 주 파티션 키에 따라 1차적으로 데이터를 분배하고, 서브 파티션 키에 따라 최종적으로 저장할 위치 (세그먼트)를 결정한다.
[Range + 해시] 결합 파티셔닝
create table 주문 (주문번호 number, 주문일자 varchar2(8), 고객id varchar2(5), ...)
partition by range (주문일자)
subpartition by hash(고객id) subpartitions 8
( partition p2009_q1 values less than ('20090401')
, partition p2009_q2 values less than ('20090701')
...
, partition p9999_mx values less than (MAXVALUE) );
[Range + 리스트] 결합 파티셔닝
CREATE TABLE 판매 (
판매점 VARCHAR2(10),
판매일자 VARCHAR2(8),
...
)
PARTITION BY RANGE (판매일자)
SUBPARTITION BY LIST (판매점)
SUBPARTITION TEMPLATE
(
SUBPARTITION lst_01 VALUES ('강남지점', '강북지점', '강서지점', '강동지점'),
SUBPARTITION lst_02 VALUES ('부산지점', '대전지점'),
SUBPARTITION lst_03 VALUES ('인천지점', '제주지점', '의정부지점'),
SUBPARTITION lst_99 VALUES (DEFAULT)
)
(
PARTITION p2009_q1 VALUES LESS THAN ('20090401'),
PARTITION p2009_q2 VALUES LESS THAN ('20090701'),
PARTITION p2009_q3 VALUES LESS THAN ('20091001'),
PARTITION p2009_q4 VALUES LESS THAN ('20100101')
);