0. 인덱스란?
인덱스는 ‘색인’이라는 뜻입니다.
색인은 책의 맨 앞 또는 맨 끝에 있는 ‘찾아보기’로 비유되곤 합니다.
요리 레시피 책을 볼 때 제가 관심있는 요리는 오직 ‘김치볶음밥’이라고 해봅시다.
이때 책의 색인(index)이 존재하지 않는다면 저는 김치볶음밥이 몇 페이지에 존재하는지 모르므로
하나 하나 책의 페이지를 넘기며 김치볶음밥 페이지를 찾아야 할 것입니다.
만약 저자가 이를 배려하여 색인(index)을 ‘김치볶음밥’ - 64p 이런 식으로 기록해놨다면
저는 1p 부터 하나씩 넘기면서 김치볶음밥을 찾지 않고 64p로 바로 찾아갈 것입니다.
DB의 인덱스의 목적도 원하는 데이터를 찾아가는 검색 속도를 향상시키기 위함입니다.
DB의 인덱스는 다음과 같이 정의할 수 있습니다.
DB 데이터의 검색 속도를 향상시키기 위한 자료구조
1. 인덱스의 특징
1-1. 항상 정렬된 상태를 유지한다.
앞의 요리 레시피 책의 색인을 생각해봐도, 요리의 개수가 많아진다면
색인 자체의 수도 많아지기 때문에 ‘김치볶음밥’을 색인에서 찾을 때도 시간이 걸리게 될 것입니다.
따라서 색인 자체도 찾기가 쉽게 ‘ㄱ’, ‘ㄴ’, ‘ㄷ’ 같은 사전 순으로 정렬되어 있는 것을 볼 수 있습니다.
DB의 인덱스도 이와 마찬가지로 컬럼의 값을 주어진 순서로 미리 정렬해서 저장합니다.
1-2. 인덱스가 설정된 컬럼은 조회 성능이 좋고, 쓰기 성능이 좋지 않다.
위의 인덱스 특징에서 ‘항상 정렬된 상태를 유지한다.’가 특징이었습니다.
이러한 특징을 가질 때 인덱스가 설정된 컬럼에 쓰기 작업이 수행된다고 해봅시다.
해당 컬럼은 인덱스가 설정되어 있어서 인덱스가 항상 정렬된 상태를 유지해야하므로
데이터가 삽입, 수정, 삭제될 때마다 인덱스는 항상 정렬 작업을 수행해야 합니다.
그렇기 때문에 쓰기 작업(INSERT, UPDATE, DELETE) 성능이 좋지 않습니다.
대신, 인덱스가 설정된 컬럼을 조회할 때는 항상 인덱스가 정렬된 상태이기 때문에
빠르게 인덱스를 찾고, 해당하는 레코드를 찾아갈 수 있으므로 조회 작업(SELECT) 성능이 향상됩니다.
결론적으로, 인덱스의 특징을 요약하면 다음과 같습니다.
인덱스는 쓰기 성능을 희생하여 조회 성능을 높인다.
2. 인덱스를 설정하면 좋은 경우
위의 인덱스의 특징을 살펴보았을 때 자연스럽게 인덱스를 설정하면 좋은 컬럼은
일반적으로 ‘쓰기가 빈번하지 않고, 조회가 빈번한 컬럼’임을 도출해낼 수 있습니다.
따라서, 인덱스를 설정하면 좋은 경우를 다음과 같이 정리할 수 있습니다.
- INSERT, UPDATE, DELETE가 자주 발생하지 않는 쓰기 작업이 적은 컬럼
- JOIN, WHERE, ORDER BY 등 조건에 자주 사용되는 컬럼
- 데이터의 중복도(Cardinality)가 낮은 컬럼
앞선 2개의 경우는 ‘쓰기가 빈번하지 않고, 조회가 빈번한 컬럼’이므로 이해할 수 있지만,
마지막에 데이터의 중복도(Cardinality)가 낮은 컬럼은 이해가 쉽게 되지 않을 수도 있습니다.
데이터의 중복도가 낮으면 왜 좋은지는 앞서 비유를 들었던 요리 레시피 책을 다시 살펴보면 알 수 있습니다.
요리 레시피 책에서는 여러 요리사의 요리 레시피가 담겨 있다고 해봅시다.
앞의 비유의 예시에서는 책의 색인이 음식의 요리 종류로 설정되어 있었습니다.
제가 찾고 싶은 것이 더 구체적으로 ‘백종원의 김치볶음밥’이라고 한다면,
책에서는 백종원 이외의 다른 요리사의 김치볶음밥도 담겨 있을 것입니다.
이때 책의 색인이 ‘음식의 요리 종류’로 설정되어 있기 때문에
‘백종원의 김치볶음밥’을 찾을 때 단순히 ‘김치볶음밥’으로 원하는 페이지를 찾게 될 것입니다.
만약 김치볶음밥 레시피가 중복되지 않고 ‘백종원의 김치볶음밥’ 하나라면
해당하는 색인에 맞는 페이지를 바로 찾을 수 있겠지만,
여러 요리사의 김치볶음밥 레시피가 존재한다면 ‘김치볶음밥’ 색인만으로는 중복도가 낮은 색인보다 검색 효율이 떨어질 것입니다.
이처럼 데이터의 중복도가 낮지 않은 컬럼에 인덱스를 설정했을 때 효율이 떨어짐을 알 수 있습니다.
여기까지, DB 인덱스의 전반적인 내용을 다뤄봤습니다.
다음에는 구체적으로 MySQL의 InnoDB에서는 인덱스를 어떻게 구현했는지 깊게 살펴보겠습니다.
Reference
Real MySQL8.0 책(저자 백은빈, 이성욱)
https://mangkyu.tistory.com/96#recentEntries
'DB' 카테고리의 다른 글
[DB] MySQL 및 InnoDB의 DB Lock 알아보기 (1) | 2023.11.19 |
---|---|
[DB] MySQL InnoDB의 인덱스(feat. 클러스터링 인덱스, 세컨더리 인덱스, 인덱스 스캔 종류, 다중 컬럼 인덱스) (1) | 2023.11.13 |
[DB] DB Lock이란? (feat. Lock 종류, 블로킹, 데드락) (0) | 2023.11.08 |
[DB] 트랜잭션 격리 수준 알아보기 (2) | 2023.09.29 |
[DB] 트랜잭션이란? (feat. ACID 특성) (2) | 2023.04.18 |