파티셔닝
: 물리적 데이터를 논리적
으로 나눔
논리적
으로는 테이블
로 접근하나, 물리적
으론 테이블 내 각각의 파티션
으로 접근세그먼트
에 해당값의 범위
로 지정쌓이는 날짜
기준 파티션포함하지 않음
create table ord_range (
ord_no number(10) not null,
ord_dt varchar2(8) not null,
ord_hms varchar2(6),
shop_no varchar2(10),
...
)
partition by range (ord_dt)(
partition p201201 values less than ('201202'),
...,
partition p_default values less than (MAXVALUE)
);
p201201
파티션에는 201202
보다 작은 값이 들어올 수 있다.
키 컬럼
을 가지고 부등호 연산
이나 between
연산을 할 경우 파티션 몇 개만 읽을 수 있음where ord_dt between '20120115' and '20120125'
위 sql은 ord_dt
를 월 단위로 나누어 저장하는데, 만약 1월 15일부터 25일까지 데이터를 sql 조회시, 1월 파티션만 읽어 결과 집합을 만든다.
값
으로 지정range 파티션
과 다르게 values()
안의 값을 사용create table bill_list(
bill_no number(10) not null,
bill_ym varchar2(6) not null,
member_id varchar2(10),
...
)
partition by list(bill_ym)(
partition p201201 values('201201'),
...,
partition p_default values(default)
);
sql문 조회 시, 일부 파티션만 읽고 처리할 수 있다.
오라클 내부
에서 지정해시 함수
를 이용해 지정한 파티션 개수로 나누어 저장create table ord_hash(
ord_no number(10) not null,
ord_dt varchar2(8),
ord_hms varchar2(6),
shop_no varchar2(10),
...
)
partition by hash (ord_no) partitions 8;
같은 값이 많지 않은 컬럼
을 사용해야 효과등치 조건
과 IN조건
으로만 사용 (해시조인과 동일)삭제
와 조회
기준으로 전략메인 파티션
과 서브 파티션
으로 구분메인 파티션
- 모든 방식의 파티션 가능(12c 이후)서브 파티션
- 모든 방식의 파티션 가능ex) 오래된 데이터를 삭제하는 일이 빈번하고, 특정 컬럼과 자주 조인
=> range-해시
또는 리스트-해시
파티션
인덱스
는 파티션 하지 않음무결성
유지테이블 파티션
과 같은 기준
으로 인덱스 나눔인덱스 생성 구문
제일 뒤에 LOCAL
키워드를 붙이면 생성 가능다른 기준
으로 인덱스 나눔파티션 키 컬럼
을 항상 파티션 인덱스
의 첫 번째 컬럼
으로 만들어야 함테이블 전체
를 읽지 않고, 필요한 파티션
만 읽을 수 있도록 하는 기능select /*+ gather_plan_statistics */ count(*)
from ord_list -- list 파티션
where ord_ym='201201';
partition list single
을 보면 리스트 파티션으로 나뉜 테이블에서 파티션 한 개
를 읽은 것이다.
select /*+ gather_plan_statistics */ count(*)
from ord_range --range 파티션
where ord_ym='201201';
처음 sql과 위의 sql의 차이는 조건절
이 필터 조건
으로 나온 것이다.
ord_ym='201201'
조건 때문인데, 오라클은 파티션 키 컬럼에 저장된 값이 하나라는 것을 알 수 없기 때문에 필터 조건으로 나온 것이다.
between
과 같은 범위 조건을 사용할 경우 해당 파티션만 액세스 할 수 있다.ex) substr(ord_ym,1,6)=:st 대신 ord_ym=substr('20120101',1,6)
merge 구문
에서의 파티션 Pruning
merge into ord_list m
using (
select ord_no,shop_no
from ord
where ord_no=7
and ord_dt='20120101') s
on (m.ord_no=s.ord_no)
when matched then update
set m.shop_no=s.shop_no;
-- partition list all로 모든 파티션을 읽게 됨
merge into (select * from ord_list where ord_ym=substr('20120101',1,6)) m
using (
select ord_no,shop_no
from ord
where ord_no=7
and ord_dt='20120101') s
on (m.ord_no=s.ord_no)
when matched then update
set m.shop_no=s.shop_no;
-- partition list single로 하나의 파티션만 읽음