[Oracle] 오라클 인덱스 클러스터 테이블, Index Cluster Table
* Cluster : (함께 자라거나 나타나는) 무리, (조밀하게 모여 있는 사람동물 등의) 무리
그럼 Index Cluster Table은 인덱스 별로 모여있는 테이블(?) 정도로 이해하면 되려나..
일단 클러스터는 DB Object 개념의 하나이다.
일반적으로 우리가 알고 있는 구조가 [테이블] ↔ [인덱스] 분리형이고
IOT가 [테이블=인덱스] 일체형이라고 한다면
인덱스 클러스터 테이블은 이 둘의 중간쯤이라고 생각하면 되겠다.
백문이 불여일견이므로 일단 직접 만들어보면서 이 놈이 어떻게 생겨먹은 놈인지 알아보도록 하자.
① 데이터를 저장할 클러스터를 생성한다.
CREATE CLUSTER C_DEPTNO (DEPTNO NUMBER(2)) INDEX;
: 클러스터의 이름을 C_DEPTNO로 정하고 인덱스로 지정할 컬럼(클러스터 키)을 DEPTNO로 정했다.
② 생성된 클러스터에 클러스터 인덱스를 정의한다.
CREATE INDEX I_DEPTNO ON CLUSTER C_DEPTNO;
: 인덱스의 이름은 I_DEPTNO이다. 아까 키 컬럼으로 정한 DEPTNO 값이 담길것이다
③ 위 클러스터에 테이블을 생성하여 담는다.
CREATE TABLE EMP CLUSTER C_DEPTNO (DEPTNO) AS SELECT * FROM SCOTT.EMP;
CREATE TABLE DEPT CLUSTER C_DEPTNO (DEPTNO) AS SELECT * FROM SCOTT.DEPT;
테스트를 위해 기존 테이블 데이터를 담았지만 아예 새로운 테이블을 생성하려면
CREATE TABLE EMP (
EMPNO NUMBER(4) PRIMARY KEY,
ENAME VARCHAR2(10),
DEPTNO NUMBER(2),
.
.
. )
CLUSTER C_DEPTNO (DEPTNO);
위와 같이 때려주면 된다.
④ 클러스터링이 제대로 됐는지 확인한다.
SELECT OWNER, TABLE_NAME FROM DBA_TABLES WHERE CLUSTER_NAME = 'C_DEPTNO';
SELECT D.DEPTNO, E.EMPNO, E.ENAME,
DBMS_ROWID.ROWID_BLOCK_NUMBER(D.ROWID) DEPT_BLOCK_NO,
DBMS_ROWID.ROWID_BLOCK_NUMBER(E.ROWID) EMP_BLOCK_NO
FROM DEPT D, EMP E
WHERE E.DEPTNO = D.DEPTNO
ORDER BY D.DEPTNO;
: 같은 키 값(DEPTNO)을 갖는 레코드들이 서로 같은 블록안에 모여있다는 것을 알 수 있다.
- 클러스터 인덱스는 일반적인 인덱스와는 달리 데이터가 Distinct되어 저장된다.
- Distinct된 인덱스는 같은 키 값을 저장하는 첫 번째 데이터 블록을 가리킨다.
- 클러스터 인덱스를 이용하면 테이블 랜덤 액세스가 키 값 하나당 한 번씩만 발생한다.
- 단일 테이블 인덱스 클러스터: 클러스터에 하나의 테이블만 담음
- 다중 테이블 인덱스 클러스터: 클러스터에 여러개의 테이블을 조인 상태로 담음
(위의 예제는 EMP 테이블과 DEPT 테이블 두 개를 담았으므로 다중 테이블 인덱스 클러스터다.)
장점
- 테이블 랜덤 액세스가 현저히 줄어들기 때문에 넓은 범위 검색 시 유리
단점
- 정해진 블록을 찾아 값을 입력해야 하므로(DEPTNO가 10이면 2312012 블록에 저장) DML 성능이 다소 떨어짐
(하지만 클러스터 키값이 자주 변동되지 않는다면 - 새로운 DEPTNO가 자주 생기지 않는다면 - 일반적인 인덱스 성능과 비슷한 수준)
- Direct Path Loading 불가
- 파티셔닝 기능 적용 불가
- 다중 테이블 클러스터 Full Scan 시 다른 테이블까지 스캔하므로 불리