Search

[데이터베이스 시스템] 인덱싱

제목
Tag
작성일

인덱스의 개념

인덱스의 필요성
대량의 데이터에서 원하는 값을 빠르게 찾기 위해
모든 데이터를 처음부터 끝까지 순차 탐색하면 매우 비효율적
인덱스(index) 는 데이터를 빠르게 찾을 수 있도록 도와주는 부가적인 구조
인덱스의 정의
인덱스: 요청된 레코드에 빠르게 접근할 수 있도록 지원하는 탐색키 + 포인터 구조
인덱싱(indexing): 인덱스를 구성하는 작업

인덱스 종류

순서 인덱스 (Ordered Index)
탐색키를 정렬된 순서대로 저장하는 인덱스
범위 탐색에 유리하고, 이진 탐색 적용 가능
해시 인덱스 (Hashed Index)
탐색키를 해시 함수로 처리해 버킷 주소를 계산
빠른 정확한 값 탐색에 적합하지만 범위 탐색에는 부적합
인덱스 평가기준
기준
설명
접근 시간
인덱스를 통해 데이터를 찾는 데 걸리는 시간
유지 비용
삽입/삭제 시 인덱스를 재구성하는 데 드는 비용
공간 비용
인덱스를 저장하는 데 필요한 추가 공간
인덱스 크기에 따른 검색 성능
인덱스 크기 > 메모리 크기: 저장된 블록을 여러번 나누어 읽어야 하기 때문에 디스크 I/O 비용증가
인덱스 크기 < 메모리 크기: 디스크 I/O 줄어 탐색시간 축소

인덱스 엔트리 구조

탐색키 값: 정렬 기준이 되는 데이터 값
포인터: 실제 레코드가 저장된 위치를 가리킴
인덱스 엔트리 구성

인덱스 구성 방식

밀집 인덱스 (Dense index)

모든 레코드에 대해 탐색키값 | 포인터 쌍(인덱스 엔트리) 유지
빠른 탐색 가능
단점: 레코드 수만큼 인덱스 크기가 커져 조회 성능 저하

희소 인덱스(Sparse index)

일부 레코드만 인덱스에 포함
검색 시 인덱스에서 근접한 블록까지 찾고, 그 블록 내에서 선형 탐색
장점: 공간 절약, 유지비용 낮음

다단계 인덱스

4KB 크기의 한 블록에 100개의 엔트리가 삽입될때, 1억개의 레코드에 대한 밀집 인덱스(천개의 블록 = 4GB 공간 필요)
인덱스의 크기가 너무 커서 메모리에 다 못 올라올 경우 인덱스 자체를 또 인덱싱하는 방식
내부 인덱스 + 외부 인덱스 구조
외부 인덱스는 내부 인덱스를 가리킴 (희소)
내부 인덱스는 실제 레코드를 가리킴 (보통 밀집)

B+ 트리 인덱스

루트노드로부터 모든 단말노드에 이르는 경로의 길이가 같은 높이 균형 트리
순서 인덱스는 파일이 커질수록 데이터 탐색에 있어서 접근 비용이 커지는 문제점을 해결하기 위해 제안
상용 DBMS에서 널리 사용되는 대표적인 순서 인덱스

구성요소

인덱스 세트 (루트 노드 + 중간 노드)
단말 노드에 도달하기 위한 경로 제공
각 노드는 탐색키와 포인터들을 포함
자식 포인터 수: 최소 ⌈n/2⌉ ~ 최대 n
순차 세트 (단말 노드들)
실제 레코드를 가리키는 포인터 포함
인접 노드끼리 링크로 연결되어 있어 범위 탐색이 효율적
탐색키 수: 최소 ⌈(n - 1)/2⌉

B+ Tree 삽입/삭제

삽입/삭제 시 중요한 특징

항상 균형 유지 (균형 트리)
삽입은 분할(split) 로 해결
삭제는 병합(merge) 또는 재분배(redistribute) 로 처리
중간 노드는 탐색만, 실제 데이터는 단말 노드에만 존재

B+ Tree 삽입 과정

1.
단말 노드에 새로운 <탐색키, 포인터> 삽입
2.
키가 많아져 노드 용량 초과 시 → 노드 분할
3.
중간값을 부모 노드로 승격
4.
부모 노드도 넘치면 재귀적으로 분할 진행
5.
트리의 높이가 증가할 수도 있음

B+ Tree 삭제 과정

1.
삭제 대상 키를 단말 노드에서 제거
2.
제거 후 키 개수가 최소 기준보다 작으면:
형제 노드와 키 재분배 시도
불가능하면 병합(merge)
3.
병합 시 부모 노드에서 해당 키 제거
4.
재귀적으로 병합되며 높이 감소 가능