오라클 인덱스
인덱스
- 원하는 데이터를 쉽게 찾을 수 있도록 돕는 책의 찾아보기와 유사한 개념
- 테이블을 기반으로 선택적으로 생성할 수 잇는 구조
- 목적은 검색성능의 최적화
- Insert, Update, Delete등과 같은 DML 작업은 테이블과 인덱스를 함께 변경해야 하기 때문에 느려질 수 있다는 단점이 존재한다.
B-Tree 기반 인덱스
오라클은 B-Tree 기반의 인덱스를 사용한다.
B-Tree는 하나의 노드에 여러 값을 가질 수 있어 적절한 높이를 유지할 수 있고 항상 Leaf노드의 높이가 일정하게 유지되는 알고리즘으로 효율적인 균형을 유지한다.
- Branch Block : 분기를 목적으로 하는 블록 : 다음 단계를 가리키는 포인터를 가지고 있다.
- Leaf Block
- 트리의 가장 아래 단계에 존재
- 인덱스 컬럼의 데이터와 row를 가리키는 포인터를 갖는다.
- 각 리프 블록 간에는 양방향 링크가 있다.
- 일치 검색과 범위 검색(양방향링크로 인해) 모두 적합하다.
클러스터형 인덱스
- 리프 블록에 row의 모든 데이터가 저장되어있다.
- 실제 데이터에 랜덤액세스를 해야되는 과정이 생략된다.(I/O작업이 줄어들기 때문에 성능적으로 효율적이다.)
- 물리적으로 정렬된상태로 데이터들이 저장된다.
- 테이블당 클러스터형 인덱스는 한개만 생성할 수 있다.
테이블 스캔
전체 테이블 스캔
- 테이블에 존재하는 모든 데이터를 읽어 가면서 조건에 맞으면 결과로서 추출하고 조건에 맞지 않으면 버리는 방식
- 전체 테이블 스캔 방식으로 읽은 블록들은 메모리에서 곧 제거될 수 있도록 관리된다.
전체 테이블 스캔 방식을 선택하는 이유는 다음과 같다.
- 조건문이 존재하지 않는 경우 : 어차피 모든 데이터를 읽어야함
- 인덱스가 존재하지 않는 경우
- 옵티마이저가 테이블의 대부분의 블록을 액세스 해야한다고 판단할 경우
- 병렬처리 방식으로 처리하는 경우
- 전체 테이블 스캔 방식의 힌트를 사용한 경우
여기서 주의해야할 것은 세번째 이유이다. 예를들면 부정조건문과 같은 조건이 있을 수 있다. 가능하다면 그러한 조건을 제거하는것이 좋을 것이다.
인덱스 스캔
- 인덱스는 인덱스 구성 컬럼과 레코드 식별자로 구성되어 있다.
- 인덱스 구성 컬럼으로 정렬되어 있다.
- 복합 인덱스일 경우 만약 A+B라면 A순으로 정렬된 후 B로정렬된다.
인덱스 스캔의 종류
- 유일 인덱스 스캔 : 단 하나의 데이터를 추출
- 인덱스 범위 스캔 : 특정 지점에서 부터 오름차순으로 검색
- 인덱스 역순 범위 스캔 : 양방향 링크를 가지고 있기 때문에 내림차순 검색도 가능하다.
전체 테이블 스캔과 인덱스 스캔 방식의 비교
인덱스 스캔은 인덱스에 존재하는 레코드 식별자를 이용해서 검색하는 데이터의 정확한 위치를 랜덤 엑세스 한다. 따라서 한번의 I/O요청에 한 블록씩 데이터를 읽는다.
반면, 전체 테이블 스캔은 한번의 I/O 요청으로 여러 블록을 한꺼번에 읽는다.
테이블의 대부분의 데이터를 읽을때는 인덱스 스캔 방식으로 한블록씩 읽는것 보다 여러블록을 함께 읽는것이 효율적일 것이다.
참조
책 : SQL 전문가 가이드 2013 Edition , KODB(한국데이터베이스진흥원)