본문 바로가기

Index 1편 - 단일인덱스와 복합인덱스

@xuv22025. 12. 15. 20:04

인덱스가 왜 필요해요 ? 

데이터베이스에서 어떤 데이터를 뒤질 때, 모든 데이터를 찾아보게 되면 이게 데이터를 뒤지는건지 내가 뒤지는건지 잘 모르겠는 순간이 온다.

이렇게 어떤 데이터를 찾을 때, 전체 데이터를 다 봐야하는 것을 DB 용어로 Full Scan 이라고 한다.

Full Scan은 말 그대로 전체 테이블을 다 봐야하니까, 당연히 처리 속도가 느리다. 그래서 자주 사용하는 필드 값의 위치를 저장해놓음으로써 데이터를 빠르게 탐색할 수 있다.

일종의 책갈피를 꽂는다고 생각하면 되는데, 검색 속도는 빨라질 수 있겠으나 데이터를 추가할 때마다 책갈피를 꽂아 넣어야 해서 데이터를 추가하는 속도는 느려질 수 있다.


인덱스의 동작 원리

인덱스는 테이블에서 원하는 데이터를 쉽고 빠르게 찾기 위해 사용한다고 했다.

그럼 그냥 인덱스라는 걸 만들기만 하면 되느냐? 그건 아니다.

어떠한 규칙으로 데이터를 빠르게 찾을건지에 대한 기준을 설정해야한다.

 

인덱스 배울 때 꾸준히 나오는 예제 : 서점

우리가 서점에서 책을 찾을 때, 어떤 기준으로 책을 찾는가?

대부분 서점들에서는 카테고리 별로 구역을 나누어둔다. 그리고 손님들은 이 카테고리를 기준으로 책을 찾는다.

이처럼 모든 책을 Book 이란 테이블에 저장할 때, 인덱스에 많이 검색할 것 같은 속성들에 대해 따로 다시 저장해 둔다.

이렇게 인덱스로 저장해두면 모든 책들을 Full Scan 하며 각 책들이 어떤 카테고리인지 일일히 확인할 필요 없이 찾고 싶은 카테고리를 범위 단위로 조회할 수 있게 된다.

위 처럼 인덱스 없이 SELECT * FROM book WHERE category = '만화' 이라고 했을 때, 모든 테이블을 검색해야 한다.

 

단일 인덱스

인덱스를 적용하는 기준은 '카테고리' 이다. 그래서 우리는 이 카테고리만 따로 때어내어 정렬해 두면 된다.

위 테이블에 인덱스를 적용한 테이블 하나를 아래처럼 추가한다면 어떤 변화가 있는지 보자.

이 인덱스가 있다면 우리는 쉽게 category = 개발 인 데이터만 한눈에 파악할 수 있다. (자세히 말하면 DB가 빠르게 범위로 탐색 가능)

어 그런데 만약 제가 category = 에세이 를 보고 싶으면 전체 데이터 다 봐야하는거 아닌가요? 라고 생각할 수 있는데, 이는 B+ 트리라는 자료구조를 통해 카테고리의 범위 단위로 데이터를 스킵할 수 있다. (다음 게시물에서 설명)

즉 개발 -> 만화 -> 에세이 순으로 3번의 탐색만에 에세이를 찾을 수 있게 되는 것이다. 

이렇게 하나의 컬럼을 대상으로 인덱스를 생성하는 것을 단일 인덱스라고 한다.

 

복합 인덱스 (인덱스 만들기만 한다고 끝이 아님 / 카디널리티)

만약 위 예시에서 카테고리 + 성인용 두가지 조건을 기준으로 검색하는 경우가 많아진다고 가정하자.

이런 경우에는 두가지 컬럼을 대상으로 인덱스를 생성하면 되는데 이는 복합 인덱스라고 한다.

예를 들어 성인용 유무 + 카테고리에 대한 복합 인덱스를 다음과 같이 생성했다고 가정하자.

이렇게 인덱스를 구현해두면 사실상 인덱스의 존재 의미가 많이 사라지게 되는데, 이유는 다음과 같다.

위 테이블의 인덱스를 따질 때는 먼저 성인용 유무를 확인하고, 이후 카테고리를 확인해야하기 때문에 너무 많은 검사를 치루게 된다.

이 인덱스가 구린 이유는 , 성인용이라는 컬럼의 카디널리티가 너무 낮아서 중복 된 데이터가 많이 발생하기 때문이다.

카디널리티란 뭔가요?

즉 성인용은 boolean -> 즉 경우의 수가 true / false로 2개이기 때문에 인덱스 생성 대상으로 적절하지 않다.

우리는 2개 뿐인 만화 카테고리를 찾고 싶은데, 오히려 데이터를 6개나 봐야하는 상황이 생긴 것이다.

그래서 오히려 우리는 반대로 카디널리티가 높은 카테고리를 먼저 탐색할 수 있도록 (카테고리, 성인용 유무) 로 인덱스를 생성해주어야한다.

(category, is_adult) 순으로 인덱스를 구현해두면 먼저 카테고리를 기준으로 거르고 (만화면 레코드 2개), 그 2개에서 성인용 유무를 따지기만 하면 된다.

이처럼 특별한 값이 많은 컬럼을 우선으로 복합 인덱스를 생성해야 빠른 데이터 탐색이 가능해진다.

xuv2
@xuv2 :: xuvlog

폭싹 늙었수다

목차