1. Index란?
인덱스(Index)란 데이터베이스에서 테이블의 특정 열에 대한 검색 성능을 향상시키기 위해 사용되는 자료구조이다. 마치 책의 맨 뒤에 있는 색인처럼, 데이터베이스에서도 인덱스를 사용하면 데이터를 더 빠르게 찾을 수 있다. 데이터를 정렬하거나 특정 값에 대해 빠르게 조회할 수 있도록 설계된 메커니즘이다.
간단하게 말하면 미리 정렬해 놓는 것이다.
예를 들어 어떤 테이블에서 id = 20인 행을 찾으려고 해보자

이 때, 컴퓨터는 id가 20인 행을 찾으려고 모든 행을 하나씩 확인해본다.
만약 row수가 10개면? 양호. 1,000개면? 양호. 10억개면? 안양호.
10억개의 row를 모두 확인한다면 너무 느리게 동작할 것이다..
이 때, index를 활용한다면 컴퓨터가 편하게 찾을 수 있다.
어떤 숫자를 찾을 때 가장 빠른 방법은 뭘까?
예를 들어, 1부터 10억까지의 숫자 중 내가 생각한 숫자를 맞춘다고 해보자.
1부터 차례대로 맞춰본다면? 만약 그 숫자가 999,999,999 였다면 거의 10억번의 질문을 해야 한다.
그렇다면 아래와 같은 방식은 어떨까?
1부터 10억의 중간 숫자인 5억보다 큰 지 확인한다.
만약 크다면 5억과 10억의 중간 숫자인 7억5천보다 큰지, 작다면 1과 5억의 중간 숫자인 2억5천보다 큰지, 이런식으로 확인한다.
이것이 바로 이진 탐색이다.

이렇게 한다면 1~10억까지의 숫자도 최대 약 30번만에 찾을 수 있다.
이것이 인덱스의 기본 개념이다.
다만, 이렇게 하려면 꼭 정렬이 되어 있어야 한다!
그래서 어떤 컬럼을 복사한 후 정렬해 놓는다. 이것이 인덱스다.
2. 상세 설명
1. 인덱스의 동작 방식
기본 개념
- 인덱스는 테이블의 열(Column)에 대해 별도의 자료구조를 생성한다.
- 이 자료구조는 대개 B-Tree 또는 Hash 기반으로 구현된다.
- 테이블의 특정 열에 대해 정렬된 상태로 유지되며, 이를 통해 데이터베이스가 원하는 데이터를 빠르게 탐색할 수 있다.
검색의 효율성
- 데이터를 검색할 때, 전체 테이블 스캔(Full Scan) 대신 인덱스를 먼저 조회하여 관련 데이터의 위치를 찾는다.
- 이를 통해 디스크 I/O를 줄이고, 성능을 크게 향상시킬 수 있다.
2. 인덱스의 종류
1) 기본(Basic) 인덱스
- Primary Index (기본 키 인덱스): 테이블의 기본 키(Primary Key)에 자동으로 생성되는 인덱스
- Unique Index (유니크 인덱스): 중복값을 허용하지 않는 인덱스. (PK는 보통 Unique Index)
2) 복합(Composite) 인덱스
- 여러 열(Column)을 결합하여 생성된 인덱스
3) 클러스터드(Clustered) 인덱스
- 데이터의 실제 저장 순서를 기준으로 생성되는 인덱스
- 한 테이블에 하나만 생성 가능
- 데이터를 저장하는 방식 자체를 정렬된 상태로 유지
- 예: MySQL InnoDB에서 기본 키(Primary Key)는 자동으로 클러스터드 인덱스가 됨
4) 비클러스터드(Non-Clustered) 인덱스
- 데이터의 저장 순서와 상관 없이 별도의 자료구조로 관리되는 인덱스
- 테이블에 여러 개 생성 가능
- 인덱스에서 데이터를 찾아 데이터가 저장된 물리적 주소로 접근
5) 전문(full-text) 인덱스
- 텍스트 검색에 최적화된 인덱스
- 예: 긴 텍스트 컬럼에서 특정 키워드를 빠르게 검색
3. 인덱스의 장점
- 검색 속도 향상
- 특정 데이터를 검색할 때 전체 테이블을 조회하지 않아도 됨
- 대량의 데이터에서 성능 차이가 극명하게 나타남
- 정렬 속도 향상
- 특정 열에 대해 정렬된 데이터를 빠르게 가져올 수 있음
- 고유성 유지
- Unique Index를 사용하면 특정 열에서 중복 데이터를 자동으로 방지 가능
4. 인덱스의 단점
- 쓰기 성능 저하
- 데이터를 삽입, 수정, 삭제할 때 인덱스도 갱신되어야 하므로 추가적인 작업이 발생
- 따라서 인덱스가 많을 수록 쓰기 성능이 저하될 수 있음
- 저장 공간 추가 필요
- 인덱스 자료구조를 별도로 관리하기 때문에 추가적인 저장 공간이 필요
- 과도한 인덱스는 성능 저하
- 모든 열에 인덱스를 생성하면 오히려 데이터베이스가 인덱스를 관리하는 데 비용이 증가
- 따라서 적절한 인덱스 설계가 필요
5. 언제 인덱스를 사용하는가?
- 조회가 빈번한 열: 검색, 정렬, 그룹화에 자주 사용되는 열
- 조인에 자주 사용되는 열: 두 테이블 간 조인 조건에 포함된 열
- WHERE 조건절에 자주 사용되는 열
3. 인덱스 자료구조
1. B-Tree (Balanced Tree)
가장 널리 사용되는 인덱스 자료구조로, 대부분의 관계형 데이터베이스 시스템(RDBMS)에서 기본적으로 사용된다.
특징:
- 균형 이진 트리가 아닌, 균형 다진 트리(Balanced Multi-way Tree)이다.
- 트리의 높이가 낮아 탐색, 삽입, 삭제 속도가 매우 빠름
- 데이터를 정렬된 상태로 유지하기 때문에 범위 검색(range query)에 적합
- 노드 하나가 여러 키와 포인터를 포함하여, 디스크 I/O를 최소화하도록 설계됨
장점:
- 범위 검색:
where age betwwen 30 and 40 같은 쿼링에 효율적
- 정렬된 데이터 유지: 인덱스를 통해 정렬된 데이터를 빠르게 가져올 수 있음
2. B+Tree (B-Tree의 변형)
B-Tree를 확장한 자료구조로, 대부분의 데이터베이스에서 사용되는 실제 구현이다.
특징:
- 모든 데이터는 리프 노드(Leaf Node)에만 저장된다.
- 리프 노드가 링크드 리스트 형태로 연결되어 있어 범위 검색 시 연속적인 데이터를 빠르게 검색할 수 있다.
- 내부 노드는 검색을 위한 키만 저장하며, 데이터는 포함하지 않는다.
장점:
- 범위 검색이 특히 빠름
- 디스크 I/O 최적화: 많은 데이터를 한 번에 읽어들일 수 있음
3. Hash (해시 테이블)
특정 값에 대해 매우 빠른 검색을 가능하게 하는 자료구조
특징:
- 해시 함수를 사용해 키를 특정 위치로 맵핑
- 데이터를 정렬하지 않으며, 정확히 일치하는 값 검색(Equal Search)에만 적합
- 범위 검색은 지원하지 않음
장점:
= 연산이 포함된 쿼리에 매우 빠른 속도를 제공
단점:
- 범위 검색과 정렬 작업에 부적합
- 충돌(해시 함수의 결과가 중복) 발생 시 성능 저하
사용 예시:
- 메모리 기반 데이터베이스(예: Redis)
- PostgreSQL의 해시 인덱스(사용 빈도는 낮음)
4. 비트맵 인덱스 (Bitmap Index)
데이터가 이산적인 값(Discrete Value)을 가질 때 사용되는 자료구조
특징:
- 데이터를 비트맵(Bit Array) 형태로 저장
- 값의 존재 여부를 0과 1로 표현
장점:
- 저장 공간 효율성: 데이터의 중복도가 높을수록 효율적
- 복잡한 조건: 여러 열의 조건이 포함된 쿼리에 효율적
- 예: where gender = 'M' and age = 30
단점:
- 데이터 변경(삽입/삭제/수정)이 잦을 경우 성능 저하
사용 예시:
- Oracle의 비트맵 인덱스
- 데이터 분석 및 OLAP(Online Analytical Processing) 워크 로드에 적합
5. GiST (Generalized Search Tree)
PostgreSQL에서 사용되는 범용 인덱스 자료구조
특징:
- B-Tree와 유사하지만, 보다 다양한 데이터 유형(텍스트, 공간 데이터 등)을 처리할 수 있다
- R-Tree(공간 데이터 처리용 트리)를 구현하는 데 적합
사용 예시:
- 공간 데이터 처리(GIS), 전체 텍스트 검색 등
- PosgreSQL의 확장 기능에서 많이 활용
6. R-Tree (Spatial Data Index)
위치나 영역 데이터를 처리하기 위해 설계된 자료구조