[Oracle Tunning] INDEX 기본
Oracle 인덱스는 데이터베이스의 성능을 최적화하기 위해 자주 사용되는 데이터 구조이다.
인덱스의 구조와 탐색 원리를 이해하면, 데이터베이스에서 효율적으로 데이터를 찾고 관리하는 데 큰 도움이 된다.
아래에서는 인덱스의 기본 개념과 인덱스의 구조적 요소들에 대해 더 깊이 알아보자.
1. 인덱스의 기본 개념
인덱스(Index)는 테이블의 열(컬럼)에 대한 정렬된 데이터 구조이다.
테이블의 데이터는 특정 순서 없이 저장되지만, 인덱스는 데이터베이스가 더 빠르게 검색할 수 있도록 특정 열의 값을 기준으로 정렬하여 별도로 관리한다.
인덱스는 책의 색인처럼 작동하여, 데이터베이스가 특정 데이터를 빠르게 찾을 수 있도록 돕는다.
B-Tree 인덱스는 Oracle에서 가장 일반적으로 사용되는 인덱스 구조이다.
B-Tree는 데이터가 정렬된 트리 구조로, 모든 노드의 높이가 균형을 이루는 트리이다. B-Tree는 효율적인 검색, 삽입, 삭제 작업을 지원하며, 데이터가 추가되거나 삭제되어도 트리의 균형이 유지되도록 설계되어 있다.
2. 시퀀셜 액세스와 랜덤 액세스의 개념
시퀀셜 액세스(Sequential Access)는 데이터를 연속적으로 읽어들이는 방식이다.
테이블의 모든 데이터를 순차적으로 읽거나, 인덱스의 리프 노드들을 순차적으로 읽어가는 방식이 이에 해당된다.
시퀀셜 액세스는 큰 데이터 블록을 한 번에 읽어들이므로 디스크 I/O 비용이 적고 빠르다는 장점이 있다.
이는 주로 Full Table Scan 또는 Full Index Scan에서 발생한다.
랜덤 액세스(Random Access)는 필요한 데이터만 선택적으로 읽어들이는 방식이다.
데이터베이스는 인덱스를 사용하여 특정 조건에 맞는 데이터를 바로 찾아간다.
예를 들어, 특정 키 값에 해당하는 데이터를 찾기 위해 인덱스를 따라가는 방식이 랜덤 액세스이다.
랜덤 액세스는 필요한 데이터를 바로 접근할 수 있지만, 여러 번의 I/O가 발생할 수 있어 시퀀셜 액세스에 비해 비용이 더 클 수 있다.
3. 인덱스의 구조적 요소
인덱스는 여러 가지 구성 요소로 이루어져 있으며, 각 요소가 데이터 검색에 중요한 역할을 한다.
- 루트 노드(Root Node): 루트 노드는 B-Tree 인덱스의 최상위 노드이다. 인덱스 탐색은 루트 노드에서 시작된다. 루트 노드는 브랜치 노드(자식 노드)들로의 경로를 결정하며, 이러한 브랜치 노드들을 통해 탐색 대상 데이터가 있는 리프 노드로 이동하게 된다.
- 브랜치 노드(Branch Node): 브랜치 노드는 루트 노드와 리프 노드 사이에 있는 중간 노드들이다. 각 브랜치 노드는 하위 노드들(다른 브랜치 노드나 리프 노드)로 가는 포인터를 포함하고 있다. 브랜치 노드는 데이터를 직접적으로 저장하지 않지만, 적절한 리프 노드로의 경로를 안내하는 역할을 한다. 브랜치 노드의 역할은 인덱스 트리의 높이를 줄여서 탐색 속도를 빠르게 하는 데 있다.
- 리프 노드(Leaf Node): 리프 노드는 인덱스 트리의 가장 하단에 위치한 노드들로, 실제로 데이터가 저장되어 있는 곳이다. 리프 노드는 인덱스 키와 해당 키 값이 있는 테이블의 행(ROWID)을 포함하고 있다. 리프 노드는 양방향 연결 리스트로 연결되어 있어, 시퀀셜 액세스가 가능하게 한다. 즉, 인덱스 탐색이 리프 노드에 도달하면, 해당 키 값에 해당하는 테이블의 행을 빠르게 찾을 수 있다.
- ROWID: 리프 노드에는 각 인덱스 키에 해당하는 테이블 행의 물리적 주소를 가리키는 ROWID가 저장된다. ROWID는 테이블에서 행이 저장된 위치를 나타내는 유일한 값으로, 이를 통해 데이터베이스는 테이블에서 해당 행을 빠르게 찾을 수 있다.
- 테이블(Table): 테이블은 데이터가 실제로 저장되는 곳이다. 인덱스는 테이블에 저장된 데이터를 빠르게 찾기 위한 보조 구조로, 인덱스 탐색이 완료되면 최종적으로 해당 데이터를 가져오기 위해 테이블에 접근하게 된다.
4. 인덱스 탐색 과정
Oracle 데이터베이스에서 인덱스를 사용한 탐색 과정은 다음과 같다.
- 루트 노드에서 시작: 쿼리의 조건에 따라 데이터베이스는 인덱스 트리의 루트 노드에서 탐색을 시작한다.
- 브랜치 노드를 통해 이동: 루트 노드에서 적절한 브랜치 노드로 이동한다. 브랜치 노드에는 해당 키 값에 맞는 하위 노드로 이동하는 포인터들이 포함되어 있다.
- 리프 노드에 도달: 브랜치 노드를 따라가며 탐색을 계속하여, 최종적으로 리프 노드에 도달한다. 리프 노드에는 조건에 맞는 인덱스 키와 관련된 테이블 행의 위치(ROWID)가 저장되어 있다.
- 테이블 접근: 리프 노드에서 얻은 ROWID를 통해 데이터베이스는 테이블에서 해당 행을 찾아 데이터를 가져온다.
끝!