본문 바로가기
DB/SQL튜닝

SQL튜닝이론 - 인덱스 파티셔닝을 통한 DML 성능향상 LOCAL PREFIXED, LOCAL NONPREFIXED, GLOBAL PREFIXED, 비파티션 인덱스

by 참외롭다 2024. 2. 7.
반응형

SQL튜닝이론 - 인덱스 파티셔닝을 통한 DML 성능향상 LOCAL PREFIXED, LOCAL NONPREFIXED, GLOBAL PREFIXED, 비파티션 인덱스

 

인덱스는 파티셔닝 여부에 따라 파티션 인덱스비파티션 인덱스로 나뉘고, 파티션 인덱스는 각 파티션이 커버하는 테이블 파티션 범위에 따라 LOCALGLOBAL로 구분됩니다.

 

- 비파티션 인덱스
- 로컬 파티션 인덱스
- 글로벌 파티션 인덱스

 

 

로컬이 아닌 파티션 인덱스는 모두 글로벌 파티션 인덱스이며, 글로벌 파티션 인덱스는 테이블 파티션과 독립적으로 구성됩니다.

 

로컬 파티션 인덱스

 

로컬 파티션 인덱스는 인덱스가 할당된 테이블의 각 파티션과 인덱스의 파티션이 서로 1대 1 대응 관계과 되도록 오라클에 의해 관리되는 파티션 인덱스를 말합니다. 로컬 파티션 인덱스는 아래와 같이 인덱스 생성 시 뒤에 LOCAL 옵션을 추가해야합니다.

 

create index 주문_x01 on 주문( 주문일자, 주문금액 ) LOCAL;
create index 주문_x02 on 주문( 고객ID, 주문일자 ) LOCAL;

 

로컬 파티션 인덱스는 테이블의 파티션과 인덱스의 파티션이 1:1로 대응합니다. 테이블의 파티션 구성을 변경하더라도 오라클에 의해 자동으로 동기화됩니다. 파티션이 변경돼도 서비스를 중단하지 않고 작업할 수 있어 관리 상의 장점이 있습니다.

 

글로벌 파티션 인덱스

 

글로벌 파티션 인덱스는 테이블의 파티션과 다르게 구성한 파티션 인덱스입니다. 파티션의 유형이 다르거나, 키가 다르거나, 기준값의 정의가 다른 경우입니다. 비파티션 테이블인 경우에도 글로벌 파티션 인덱스를 생성할 수 있습니다. 아래와 같인 인덱스 생성 시 뒤에 GLOBAL 옵션을 추가하고 인덱스의 파티션을 별도로 정의해야 합니다.

 

create index 주문_x03 on 주문 (주문금액, 주문일자) GLOBAL
partition by range(주문금액) (
  partition P_01 values less than (100000)
  partition P_MX values less than (MAXVALUE) -- 주문금액 >= 100000
)

 

글로벌 파티션 인덱스는 테이블 파티션 구성을 변경하는 순간 UNUSABLE 상태로 바뀌므로 인덱스를 재성성해 야합니다. 그동안 해당 테이블의 사용을 중단해야 합니다. 글로벌 파티션 인덱스도 테이블과 정확히 1:1 관계가 될 수 있지만 오라클이 테이블 변경 시 자동으로 관리하지 않기 때문에 로컬 파티션 인덱스로 불 수 없습니다.

 

비파티션 인덱스

 

비파티션 인덱스는 파티셔닝 하지 않은 인덱스로 테이블의 여러 파티션을 가리키기 때문에 글로벌 비파티션 인덱스라고 부르기도 합니다. 마찬가지로 테이블 파티션 구성을 변경하는 순간 UNUSABLE 상태로 바뀌므로 인덱스를 재구성해야 합니다.

 

PREFIXED 파티션 인덱스와 NONPREFIXED 파티션 인덱스의 차이점

 

파티션 인덱스는 PREFIXED와 NONPREFIXED로 나눌 수 있습니다. 인덱스 파티션 키 칼럼이 인덱스 구성의 선두 컬럼인지 여부에 따른 구분입니다.

 

- PREFIXED : 인덱스 파티션 키 컬럼이 인덱스 키 컬럼 왼쪽 선두에 위치한다.

 

- NONPREFIXED : 인덱스 파티션 키 컬럼이 인덱스 키 컬럼 왼쪽 선두에 위치하지 않는다. 파티션 키가 인덱스 칼럼에 아예 속하지 않을 때도 여기에 속한다

 

글로벌 파티션 인덱스는 PREFIXED 인 파티션에만 지원되므로 결과적으로 파티션 인덱스는 네 가지 유형을 정리할 수 있습니다.

 

- LOCAL PREFIXED 파티션 인덱스
- LOCAL NONPREFIXED 파티션 인덱스
- GLOBAL PREFIXED 파티션 인덱스
- 비파티션 인덱스

 

select i.index_name, i.partitioned p.partitioing_type, p.locality, p.alignment
from user_indexes i, user_part_indexes p
where i.table_name = '주문'
and p.index_name(+) = i.index_name
order by i.index_name;

-- index_name   par   partition   local   aligment
-- 주문_x01      YES    RANGE       LOCAL   PREFIXED
-- 주문_x02      YES    RANGE       LOCAL   NON_PREFIXED
-- 주문_x03      YES    RANGE       GLOBAL   PREFIXED
-- 주문_x04      NO

 

중요한 인덱스 파티션 제약

 

UNIQUE 인덱스를 파티셔닝 하려면 파티션의 기준 키가 모두 인덱스의 구성 칼럼이어야 합니다. PK 가 '주문일자 + 주문번호'이고 '주문일자'로 파티셔닝 한 주문 테이블이 있다고 가정합니다. PK가 로컬 파티션이면 PK 인덱스를 테이블 파티션키와 같은 주문일자로 파티셔닝한 셈으로 인덱스 파티션의 키가 인덱스의 구성 칼럼입니다. 이 상태에서 레코드를 입력하면 중복 값 확인을 위해 값의 범위에 해당하는 파티션 인덱스만 탐색하면 됩니다.

 

만약 PK가 주문번호 단일 칼럼인 로컬 파티션 인덱스라면 테이블이 주문일자로 파티션 된 경우 인덱스의 파티션키가 인덱스의 구성 칼럼이 아닙니다. 위의 제약으로 인해 인덱스를 파티셔닝 할 수 없지만 파티셔닝이 허용된다면 특정 주문번호 레코드를 입력하기 위해 인덱스 파티션 모두를 탐색해야 합니다. 주문번호가 어떤 파티션에도 입력될 수 있기 때문입니다. 게다가 레코드를 입력하고 커밋하기 전까지, 다른 트랜잭션이 같은 주문번호를 다른 파티션에 입력하는 현상을 막기 위해 추가적인 LOCK 메커니즘도 필요합니다. 이처럼 UNIQUE인덱스를 파티셔닝 할 때, 파티션 키 인덱스 칼럼에 포함돼야 한다는 조건은 DML의 성능 보장을 위함입니다.

 

이 제약으로 인해 PK 인덱스를 로컬 파티셔닝하지 못하면 테이블의 파티션 구조 변경작업이 어렵습니다. 테이블 파티션 구성을 변경하는 순간 pK 인덱스가 UNUSABLE 상태로 바뀌기 때문에 테이블의 사용을 중단해야 하기 때문입니다. 이를 방지하기 위해 가급적 인덱스를 로컬 파티션으로 구성해야 하며 테이블을 설계할 때 파티션을 고려해 pk를 잘 구성해야 합니다.

반응형