데이터베이스를 사용하다 보면 쿼리의 성능을 높이기 위해 인덱스를 추가하는 경우가 있다.
많은 주니어 개발자들이 경험하듯, 인덱스를 추가하면 데이터 조회 속도가 빨라지는 것을 자주 경험하게 된다.
하지만 그 원리를 정확히 이해하지 못하면 잘못된 인덱스를 생성해 오히려 성능을 저하시키기도 한다.
이번 글에서는 인덱스의 원리와 성능에 미치는 영향을 그림을 통해 쉽게 설명해보고자 한다.
인덱스의 기본 개념
- 인덱스는 책의 목차와 유사한 개념이다. 책에서 원하는 내용을 찾을 때 처음부터 끝까지 한 페이지씩 넘겨보는 것보다 목차를 통해 원하는 챕터나 페이지를 바로 찾는 것이 훨씬 빠르듯이, 데이터베이스에서도 인덱스는 특정 열(column)에 대한 참조 테이블을 만들어서 데이터 조회를 빠르게 도와준다.
인덱스의 작동 방식
- DB 테이블에 인덱스가 생성되면, DBMS는 해당 테이블의 특정 열에 대한 정렬된 구조를 생성하게 된다.
- 이 구조는 B-Tree나 해시 테이블(Hash Table)과 같은 자료 구조를 사용하여 데이터의 위치를 빠르게 찾도록 설계되어 있다.
- B-Tree 인덱스: 가장 일반적인 인덱스 유형이며, 데이터가 정렬된 상태로 트리에 저장된다. 쿼리에서 WHERE 조건으로 특정 열을 검색할 때, B-Tree를 통해 트리를 탐색하며 원하는 데이터를 빠르게 찾을 수 있다.
- 해시 인덱스: 해시 함수(Hash Function)를 사용하여 키-값 매핑을 만들기 때문에 정확한 매칭을 찾는 데에 매우 빠르다. 하지만 범위 검색(range query)에는 적합하지 않다.
- 왼쪽: 인덱스 없는 경우
테이블의 모든 행을 처음부터 하나하나 살펴보는 방식이다. 원하는 데이터를 찾기 위해 모든 행을 확인해야 하므로 시간이 오래 걸린다. - 오른쪽: 인덱스가 적용된 경우
B-Tree 구조를 통해 원하는 데이터를 빠르게 찾아가는 모습을 보여준다. 원하는 값의 위치를 바로 찾아갈 수 있어 조회 속도가 크게 향상된다.
인덱스가 성능을 높이는 이유
- 인덱스가 쿼리 성능을 향상시키는 이유는 바로 데이터 조회 방식을 개선하기 때문이다.
- 인덱스가 없을 때는 테이블의 모든 데이터를 처음부터 끝까지 검색하는 풀 테이블 스캔(Full Table Scan)이 발생한다.
- 하지만 인덱스를 사용하면 필요한 데이터에 대한 위치 정보를 이용해 일부 데이터만 조회하면 되기 때문에 성능이 크게 향상된다.
더보기
예를 들어, 한 테이블에 1,000,000개의 레코드가 있다고 가정하자. 만약 인덱스가 없으면 특정 열을 기준으로 데이터를 검색할 때 1,000,000개의 레코드를 모두 확인해야 한다. 반면에, 인덱스가 있다면 1,000,000개의 레코드를 모두 확인할 필요 없이 일부만 탐색하면 된다.
인덱스의 단점과 잘못된 인덱스 사용
- 인덱스는 장점만 있는 것이 아니다. 잘못된 인덱스 사용은 오히려 성능을 떨어뜨릴 수 있다.
- 인덱스의 추가 비용: 인덱스를 만들면 데이터베이스가 데이터를 삽입하거나 업데이트할 때마다 인덱스를 관리해야 한다. 이는 쓰기 작업(insert, update, delete)의 성능 저하를 유발할 수 있다.
- 너무 많은 인덱스: 각 인덱스는 별도의 저장 공간을 차지하고, 쿼리 실행 시 어떤 인덱스를 사용할지 결정하는 데 시간이 추가로 소요될 수 있다.
- 잘못된 열에 인덱스 생성: 자주 사용되지 않는 열이나 데이터가 균일하게 분포되어 있지 않은 열에 인덱스를 생성하면 인덱스의 이점을 얻기 힘들다.
더보기
예를 들어, gender와 같은 열에 인덱스를 생성하는 경우를 생각해보자. 만약 테이블의 모든 행이 gender 열에서 'Male' 또는 'Female'만을 가진다면, 해당 인덱스는 데이터 필터링에 큰 도움을 주지 못한다.
결론
- DB 인덱스는 쿼리 성능을 높이기 위한 매우 중요한 도구이지만, 그 동작 원리와 어떤 상황에서 이점을 얻을 수 있는지 이해하고 사용하는 것이 중요하다.