매일메일

데이터베이스 인덱스에 대해 설명하기

jonghyeon6084 2025. 4. 26. 17:47
728x90

- 인덱스는 DB에서 테이블의 검색 속도를 향상시키기 위한 자료구조이다. 저장되는 컬럼의 값을 사용하여 항상 정렬된 상태를 유지하는 것이 특징이다. 이러한 특징으로 인해 인덱스는 INSERT, UPDATE, DELETE의 성능이 희생되는 것이 단점이다.

DB별 index 자료구조

요약

1. MySQL(InnoDB)

 - 기본은 B+Tree 인덱스
 - Primary Key 인덱스는 클러스터형(데이터 자체를 가지고 있음)
 - **Secondary Index(보조 인덱스)**는 PK를 참조한다.
B+Tree란??
 - 모든 데이터는 리프 노드에만 저장.
 - 리프 노드끼리 포인터로 연결되어 있음.(범위 검색에 유리)
 - 부모 노드는 키 값만 가지고 있음.

2. Oracle

- B-Tree or B+Tree를 사용
- 일반 인덱스에는 B-Tree 기반.
- **Clustered Index도 지원**

3. PostgreSQL

- 기본은 B+Tree 인덱스
- 특이하게 다양한 인덱스 종류를 지원함(Hash 인덱스, GiST, GIN, BRIN, SP-GiST)

4. SQL Server

- 기본은 B+Tree 인덱스
- Clustered Index(데이터 자체를 정렬)와 Non-clustered Index(포인터만 저장)가 명확히 구분된다.

5. MonogoDB

- 내부적으로 B-Tree 기반 인덱스를 사용
- (정확히는 B-Tree를 약간 수정해서 사용)

B-Tree와 B+tree는 무엇??

둘다 트리 자료구조이다.
 - B-Tree는 데이터를 "균형 있게" 저장하는 트리
 - B+Tree는 B-Tree를 약간 수정해서, 검색과 범위조회를 더 빠르게 만든 구조
> 비유하자면, B-Tree는 도서관에 책이 층마다 분산되어 있는 구조, B+Tree는 책 리스트(목록)가 한 층에 다 정리되어 있어서 빠르게 훑을 수 있는 구조 

B-Tree
 - 데이터(키)가 모든 노드(루트/중간/리프)에 저장된다.
 - 삽입/삭제할 때 균형을 맞추려고 노드를 분할하거나 합친다.
 - 검색은 루트 -> 자식-> ... 식으로 내려가면서 한다.

B+tree
 - 실제 데이터는 리프 노트에만 저장한다.
 - 루트/중간 노드에는 검색용 키만 가지고 있다.
 - 리프 노드끼리 포인터로 연결되어 있어서 범위 조회를 매우 빠르게 할 수 있다.

>> 즉 B-Tree는 "찾고 끝"이라면 B+Tree는 "찾고 옆으로 쭉쭉 훑을 수 있음"이 장점

DB의 대표적인 스캔의 종류

스캔종류 설명
Full Table Scan 테이블을 처음부터 끝까지 전부 읽음(가장 비용 큼)
Index Scan(Range Scan) 인덱스를 사용해 필요한 레코드만 빠르게 읽음(좋음)
Index Only Scan(Covering Index Scan) 인덱스에 필요한 모든 컬럼이 있으면 테이블가지 가지 않고 인덱스에서 바로 읽음(더 좋음)
Index Skip Scan 인덱스의 일부 컬럼만 조건에 걸렸을 때 그룹별로 스캔
Bitmap Index Scan 다수의 비트맵 인덱스를 조합해 조건 필터링(AND/OR 효율적)

MySQL(특히 InnoDB 기준)

스캔 방식 설명
Full table Scan 테이블 전체를 훑음
Index Range Scan 인덱스를 이용해 구간 범위를 스캔
Index Full Scan 인덱스를 처음부터 끝까지 읽음
Index Skip Scan 복합 인덱스 중 앞부분 컬럼 조건이 없을 때 똑똑하게 일부 스캔
Index Only Scan 인덱스만 보고 결과 반환(테이블로 안 가도 됨)
- Index Range Scan이 가장 많이 쓰임.
- 복합 인덱스 앞 컬림이 where에 걸리지 않으면 스킵 스캔 시도함.

Oracle

스캔 방식 설명
Full Table Scan 테이블 전체 블록 읽기
Index Range Scan 범위 조건에 맞게 인덱스 읽기
Index Unique Scan 유니크 조건 걸릴 때 하나만 찾음
Index Full Scan 인덱스를 전체 읽지만 순서대로. 정렬 최적화
Index Fast Full Scan 인덱스를 랜덤 읽기로 전체 스캔(순서 무시, 빠른 읽기)
Bitmap Index Scan Bitmap 인덱스를 활용해서 필터링(값 종류가 적을 때)
Index Skip Scan 복한 인덱스의 선두 컬럼 없이 검색할 때
- Index Unique Scan이 가장 빠름(정확한 PK값 찾기)
- 대량 데이터는 Bitmap Index Scan 활용할 수도 있음.

PostgreSQL

스캔 방식 설명
Seq Scan 테이블 전체 읽기
Index Scan 인덱스를 따라가면서 테이블 튜플 찾기
Index Only Scan 인덱스만 보고 결과 만들기
Bitmap Scan 여러 인덱스 조건 조합할 때 비트맵으로 빠르게 처리
TID Scan 특정 Tuple ID를 직접 접근
- Index Only Scan이 매우 강력(VACUUM이 잘 되어 있어야 함)
- Bitmap Scan을 엄청 적극적으로 활용(AND/OR 조건 최적화)

SQL Server

스캔 방식 설명
Table Scan 테이블 전체 읽기
Index Seek 인덱스 찾아서 바로 해당 위치로 이동
Index Scan 인덱스를 쭉 읽음
RID Lookup / Key Lookup 인덱스에서 PK 찾아서 테이블 레코드 읽기
Columnstore Scan Columnstore 인덱스 기반으로 컬럼 단위 스캔
- Index Seek가 뜨면 최고.(바로 점프해서 찾음)
- Key Lookup은 성능이 나빠질 수 있음(인덱스만 보고 끝나지 않고 테이블까지 다시 가니까)