(1) 인덱스 파티션 유형
(2) 로컬 파티션 인덱스
(4) 글로벌 파티션 인덱스
alter table ...
split partition ...
update global indexes;
- 파티션 DDL로 인해 영향 받는 레코드가 전체의 5% 미만일 때만 유용
테이블 파티션과의 관계
글로벌 해지 파티션 인덱스
(5) Prefixed vs. Nonprefixed
(6) 파티션 인덱스 구성 예시
인덱스 파티셔닝 예제
kjwon:ora10g:KJWON >
l create table t ( gubun
2 , seq, seq_name, seq_cls
3 , seq2, seq2_name, seq2_cls
4 )
5 partition by range(seq) (
6 partition p1 values less than(100)
7 , partition p2 values less than(200)
8 , partition p3 values less than(300)
9 , partition p4 values less than(maxvalue)
10 )
11 as
12 select 1
13 , rownum, dbms_random.string('u', 10), 'A'
14 , round(dbms_random.value(1, 400)), dbms_random.string('l', 10), 'B'
15 from dual
16 connect by level <= 400 ;
테이블이 생성되었습니다.
- seq 컬럼 기준으로 Range 파티셔닝
kjwon:ora10g:KJWON >
l create unique index t_idx1 on t(gubun, seq2) LOCAL ;
create unique index t_idx1 on t(gubun, seq2) LOCAL
*
1행에 오류:
ORA-14039: 열을 분할영역한 것은 UNIQUE 인덱스로 키 열의 부분 집합을 폼 합니다
- Unique 파티션 인덱스를 만들 때는 파티션 키 컬럼이 인덱스 컬럼에 포함돼 있어야 한다.
kjwon:ora10g:KJWON >
l create unique index t_idx1 on t(gubun, seq2) ;
인덱스가 생성되었습니다.
- 비파티션 인덱스를 만들 때는 그런 제약이 없다.
kjwon:ora10g:KJWON >
l create unique index t_idx2 on t(gubun, seq) LOCAL ;
인덱스가 생성되었습니다.
- 파티션 키를 인덱스 구성 컬럼에 포함시켜 unique 인덱스 생성
kjwon:ora10g:KJWON >
l create index t_idx3 on t(seq, gubun) LOCAL ;
인덱스가 생성되었습니다.
- 로컬 prefixed 파티션 인덱스 생성
kjwon:ora10g:KJWON >
l create index t_idx4 on t(seq_name, seq) LOCAL ;
인덱스가 생성되었습니다.
- 로컬 Nonprefixed 파티션 인덱스 생성
kjwon:ora10g:KJWON >
l create index t_idx5 on t(seq_cls, seq) GLOBAL
2 partition by range(seq) (
3 partition p1 values less than(100)
4 , partition p2 values less than(200)
5 , partition p3 values less than(300)
6 , partition p4 values less than(maxvalue)
7 )
8 ;
partition by range(seq) (
*
2행에 오류:
ORA-14038: GLOBAL로 분할영역된 인덱스는 접두사이어야 합니다
- 글로벌 파티션 인덱스에는 Nonprefixed 인덱스가 허용되지 않는다.
kjwon:ora10g:KJWON >
l create index t_idx5 on t(seq, seq_cls) GLOBAL
2 partition by range(seq) (
3 partition p1 values less than(100)
4 , partition p2 values less than(200)
5 , partition p3 values less than(300)
6 , partition p4 values less than(maxvalue)
7 ) ;
인덱스가 생성되었습니다.
- 글로벌 Prefixed 파티션 인덱스 생성
- 테이블 파티션과 100% 같게 정의하더라도 이를 '로컬 파티션 인덱스'라고 부르지 않는다.
kjwon:ora10g:KJWON >
l create index t_idx6 on t(seq, seq_name) GLOBAL
2 partition by range(seq) (
3 partition p1 values less than(200)
4 , partition p2 values less than(maxvalue)
5 ) ;
인덱스가 생성되었습니다.
- 각 인덱스 파티션이 두 개 테이블 파티션과 매핑
kjwon:ora10g:KJWON >
l create index t_idx7 on t(seq, seq_name, seq_cls) GLOBAL
2 partition by range(seq) (
3 partition p1 values less than(50)
4 , partition p2 values less than(100)
5 , partition p3 values less than(150)
6 , partition p4 values less than(200)
7 , partition p5 values less than(250)
8 , partition p6 values less than(300)
9 , partition p7 values less than(350)
10 , partition p8 values less than(maxvalue)
11 ) ;
인덱스가 생성되었습니다.
- 두 개 인덱스 파티션이 한 개 테이블 파티션과 매핑되는 구조
kjwon:ora10g:KJWON >
l create index t_idx8 on t(seq2) GLOBAL
2 partition by range(seq2) (
3 partition p1 values less than(100)
4 , partition p2 values less than(200)
5 , partition p3 values less than(300)
6 , partition p4 values less than(maxvalue)
7 ) ;
인덱스가 생성되었습니다.
- 테이블과 다른 컬럼으로 파티셔닝할 때는 항상 M:M 관계 형성
kjwon:ora10g:KJWON >
l select i.index_name, i.uniqueness, p.locality
2 , p.alignment, i.partitioned, p.partition_count
3 from user_indexes i, user_part_indexes p
4 where i.table_name = 'T'
5 and p.table_name(+) = i.table_name
6 and p.index_name(+) = i.index_name
7 order by 1 ;
INDEX_NAME UNIQUENES LOCALI ALIGNMENT PAR PARTITION_COUNT
------------------------------ --------- ------ ------------ --- ---------------
T_IDX1 UNIQUE NO
T_IDX2 UNIQUE LOCAL NON_PREFIXED YES 4
T_IDX3 NONUNIQUE LOCAL PREFIXED YES 4
T_IDX4 NONUNIQUE LOCAL NON_PREFIXED YES 4
T_IDX5 NONUNIQUE GLOBAL PREFIXED YES 4
T_IDX6 NONUNIQUE GLOBAL PREFIXED YES 2
T_IDX7 NONUNIQUE GLOBAL PREFIXED YES 8
T_IDX8 NONUNIQUE GLOBAL PREFIXED YES 4
8 개의 행이 선택되었습니다.
(7) 글로벌 파이션 인덱스의 효용성
(8) 로컬 Nonprefixed 파티션 인덱스의 효율성
create table 일별계좌별거래 (
계좌번호 number
, 거래일자 date
, 거래량 number
, 거래금액 number
)
partition by range(거래일자)(
partition p01 values less than(to_date('20090201', 'yyyymmdd'))
, partition p02 values less than(to_date('20090301', 'yyyymmdd'))
, partition p03 values less than(to_date('20090401', 'yyyymmdd'))
, partition p04 values less than(to_date('20090501', 'yyyymmdd'))
, partition p05 values less than(to_date('20090601', 'yyyymmdd'))
, partition p06 values less than(to_date('20090701', 'yyyymmdd'))
, partition p07 values less than(to_date('20090801', 'yyyymmdd'))
, partition p08 values less than(to_date('20090901', 'yyyymmdd'))
, partition p09 values less than(to_date('20091001', 'yyyymmdd'))
, partition p10 values less than(to_date('20091101', 'yyyymmdd'))
, partition p11 values less than(to_date('20091201', 'yyyymmdd'))
, partition p12 values less than(maxvalue)
) ;
declare
l_first_date date;
l_last_day number;
begin
for i in 1..12
loop
l_first_date := to_date('2009' || lpad(i, 2, '0') || '01', 'yyyymmdd');
l_last_day := to_number(to_char(last_day(l_first_date), 'dd'));
insert into 일별계좌별거래
select rownum 계좌번호
, l_first_date + mod(rownum, l_last_day) 거래일자
, round(dbms_random.value(100, 10000)) 거래량
, round(dbms_random.value(10000, 1000000)) 거래금액
from dual
connect by level <= 10000;
end loop;
end;
/
create index local_prefix_index on 일별계좌별거래(거래일자, 계좌번호) local;
create index local_nonprefix_index on 일별계좌별거래(계좌번호, 거래일자) local;
select /*+ index(t local_prefix_index) */ sum(거래량), sum(거래금액)
from 일별계좌별거래 t
where 계좌번호 = 100
and 거래일자 between to_date('20090115', 'yyyymmdd')
and to_date('20091215', 'yyyymmdd')
;
Call Count CPU Time Elapsed Time Disk Query Current Rows
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Parse 1 0.000 0.000 0 0 0 0
Execute 1 0.000 0.000 0 0 0 0
Fetch 2 0.016 0.023 0 387 0 1
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Total 4 0.016 0.023 0 387 0 1
Misses in library cache during parse: 0
Optimizer goal: ALL_ROWS
Parsing user: KJWON (ID=64)
Rows Row Source Operation
------- ---------------------------------------------------
0 STATEMENT
1 SORT AGGREGATE (cr=387 pr=0 pw=0 time=22846 us)
11 PARTITION RANGE ALL PARTITION: 1 12 (cr=387 pr=0 pw=0 time=16366 us)
11 TABLE ACCESS BY LOCAL INDEX ROWID 일별계좌별거래 PARTITION: 1 12 (cr=387 pr=0 pw=0 time=22704 us)
11 INDEX RANGE SCAN LOCAL_PREFIX_INDEX PARTITION: 1 12 (cr=376 pr=0 pw=0 time=8009 us)(Object ID 52990)
select /*+ index(t local_nonprefix_index) */ sum(거래량), sum(거래금액)
from 일별계좌별거래 t
where 계좌번호 = 100
and 거래일자 between to_date('20090115', 'yyyymmdd')
and to_date('20091215', 'yyyymmdd')
;
Call Count CPU Time Elapsed Time Disk Query Current Rows
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Parse 1 0.000 0.000 0 0 0 0
Execute 1 0.000 0.000 0 0 0 0
Fetch 2 0.000 0.001 0 35 0 1
------- ------ -------- ------------ ---------- ---------- ---------- ----------
Total 4 0.000 0.001 0 35 0 1
Misses in library cache during parse: 0
Optimizer goal: ALL_ROWS
Parsing user: KJWON (ID=64)
Rows Row Source Operation
------- ---------------------------------------------------
0 STATEMENT
1 SORT AGGREGATE (cr=35 pr=0 pw=0 time=544 us)
11 PARTITION RANGE ALL PARTITION: 1 12 (cr=35 pr=0 pw=0 time=532 us)
11 TABLE ACCESS BY LOCAL INDEX ROWID 일별계좌별거래 PARTITION: 1 12 (cr=35 pr=0 pw=0 time=433 us)
11 INDEX RANGE SCAN LOCAL_NONPREFIX_INDEX PARTITION: 1 12 (cr=24 pr=0 pw=0 time=232 us)(Object ID 53003)
select 계좌번호, count(*)
from 일별계좌별집계
where 거래일자 between '20090101' and '20090115'
group by 계좌번호;
- 계좌번호만으로 인덱스를 생성하면 거래일자를 읽기 위한 테이블 액세스가 발생하므로 불리
(9) 엑세스 효율을 고려한 인덱스 파티셔닝 선택 기준
DW성 애플리케이션 환경
OLTP성 애플리케이션 환경
(10) 인덱스 파티셔닝 제약을 고려한 데이터베이스 설계