■ Unique, Non-unique 인덱스
  - 유니크 인덱스가 효율이 좋음.


■ 결합 인덱스
  - 여러 컬럼값을 조합하여 하나의 인덱스화
  ○ 결합 인덱스 우선순위

1) =
2) in
3) like 'K%'
4) between
5) <>
6) like '%K'


■ 인덱스 구조에 따른 구분
  - B*Tree
  - Bitmap
  - Reverse key
  - Descending
  - Function-based


◆ B*Tree 인덱스
  - 인덱스는 만들어질 때 밑에서부터 차곡차곡 채워진다. 하지만 인덱스가 사용될 때는 위에서부터 사용되어진다.
  - B*Tree의 Root블록과 Branch블록은 책으로 치면 목차와 같다.
  - 각 Leaf블록은 양 옆의 블록에 대한 정보를 가지고 있어서, 만약 Range scan을 한다면 처음의 Leaf블록으로 간 다음 다시 Root블록부터 찾는 것이 아니라 Leaf블록에서 다음 Leaf블록의 주소를 가지고 바로 다음 Leaf블록으로 넘어간다.
  - B*Tree인덱스는 Root를 기준으로 반을 딱 나눴을 때 양쪽의 비유리 같아야 효율이 가장 좋다. 만약 밸런스가 깨지면 인덱스를 사용해도 속도가 현저히 떨어진다.
  - 데이터를 찾을 때 인덱스의 모든 블록을 다 메모리로 끌어올리는 것이 아니라 필요한 인덱스 블록들만 끌어올리는 것이다.



◆ Bitmap 인덱스
  ▷ Bit로 맵을 만드는 인덱스
  ▷ Cardinality의 갯수(값의 종류 수)로 맵을 만든다.
  ▷ 만약 회원 테이블에서 회원들의 주민등록번호로 맵을 만든다면 회원 수만큼의 인덱스 로우수 때문에 어마어마한 크기와 비효율적인 인덱스가 만들어질 것이다.
  ▷ 또한 B*Tree는 데이터 하나가 바뀌면 인덱스에서 해당 데이터에 대한 것만 바뀌면 되는데, 비트맵 인덱스는 하나 때문에 나머지 모든 비트맵도 영향을 받는다.

  ○ 장점
    - Cardinality가 낮은 컬럼에 대해 사용
    - AND/OR 등으로 결합된 복합 조건에 최적
    - Null 컬럼도 인덱스에 저장
    - DW 등 대량의 데이터를 읽기전용으로 사용시에 적당 

  ○ 단점
    - DML 작업에 취약
    - RBO에서는 사용 못함
    - Online 옵션 사용 못함(인덱스 리빌드 시)

  ○ 조건
    - 일단 비트맵 인덱스는 Cardinality가 낮아야 하고, 데이터가 DML이 적게 일어나는 컬럼에 만들어주면 좋다.

  ○ 생성
SQL> create bitmap index 인덱스명 on 테이블명(컬럼명);



◆ 역방향 인덱스(Reverse Index)
  - 연속된 데이터를 지우거나 관리하는 경우에는 이전의 데이터들을 지워버리면 한쪽의 데이터가 쑤~욱 지워진 것이기 때문에 인덱스의 밸런스가 깨져버려 효율이 안좋아진다.
  - 그래서 그 대안으로 해당 컬럼의 값을 뒤집어서 그 값을 ROWID와 매칭시켜 인덱스를 만들어버리면, 후에 연속된 데이터가 지워지더라도 균등하게 지워지기 때문에 인덱스의 밸런스가 유지된다. 그래서 나온 것이 역방향 인덱스이다.
  ○ 생성
SQL> create index 인덱스명 on 테이블명(컬럼명) reverse;

  ○ 역방향 인덱스를 확인하는 방법
SQL> select index_name, index_type
   from user_indexes
   where index_name = '인덱스명';



◆ Descending Index
  - 일반적인 인덱스는 기본적으로 오름차순으로 생성됨
  - 그러나 Descending 내림차순으로 데이터가 정렬되기 때문에, 날짜 데이터 등을 조회할 때 최신 날짜를 먼저 조회하는 경우 등에 아주 유리함.
  ○ 생성
SQL> create index 인덱스명 on 테이블명(컬럼명 desc);



◆ 함수기반 인덱스(Function-Based Index)
  - 8i부터 추가된 기능
  - 기존의 방식대로라면 인덱스가 걸려있는 컬럼에는 쿼리조건에 가공을 하면 안되었다. 옵티마이저는 where 다음부터 부등호가 나오기 전까지의 것을 하나의 컬럼으로 인식한다. 그 컬럼에 인덱스가 걸려있다면 인덱스를 타는데 만약 가공이 되어 있다면 인덱스가 잘 만들어져 있더라도 그것을 타지 못하고 풀스캔을 해버린다.
  - 함수기반인덱스는 그 가공된 상태(함수 또는 계산식)를 인덱스로 만들기 때문에, 위의 경우라 해도 인덱스를 탈 수 있게끔 해준다.

  ○ 생성
SQL> alter session set QUERY_REWRITE_ENABLED=TRUE;
SQL> alter session set QUERY_REWRITE_INTEGRITY=TRUSTED;

SQL> create index 인덱스명 on 테이블명(가공된컬럼);
여기서 가공된 컬럼이라는 것은 컬럼이 함수와 함께 쓰이거나 계산식에 쓰인 경우 등을 말함.
Posted by 겨울섬
,