개발자도구
데이터베이스 인덱스는 왜 검색을 빠르게 만들까
수백만 건의 데이터가 쌓인 테이블에서 특정 조건에 맞는 행을 찾을 때, 인덱스가 있는 테이블과 없는 테이블의 속도 차이는 극적으로 벌어질 수 있습니다. 이 차이를 이해하려면 인덱스가 없을 때 데이터베이스가 무엇을 하고 있는지부터 살펴봐야 합니다.
인덱스가 전혀 없는 테이블에서 조건에 맞는 데이터를 찾으려면, 데이터베이스는 첫 번째 행부터 마지막 행까지 순서대로 하나하나 확인하는 전체 스캔을 할 수밖에 없습니다. 이는 마치 색인이 없는 두꺼운 책에서 특정 단어가 나온 페이지를 찾기 위해 처음부터 한 장씩 넘겨보는 것과 같습니다. 데이터가 적을 때는 큰 문제가 안 되지만, 행 수가 늘어날수록 걸리는 시간도 거의 그만큼 비례해서 늘어납니다.
인덱스는 이 문제를 해결하기 위해, 특정 컬럼의 값들을 미리 정렬된 별도의 자료구조(대표적으로 B-Tree)로 만들어 둡니다. 책의 맨 뒤에 있는 색인처럼, "이 값은 몇 번째 페이지(행)에 있다"는 정보를 빠르게 찾아갈 수 있는 지도를 미리 만들어두는 셈입니다. 정렬된 구조 덕분에 데이터베이스는 이진 탐색과 비슷한 방식으로 원하는 값을 훨씬 적은 비교 횟수만으로 찾아낼 수 있습니다.
다만 인덱스가 공짜는 아닙니다. 데이터를 추가하거나 수정할 때마다, 실제 데이터뿐 아니라 이 정렬된 색인 구조도 함께 갱신해야 하므로 쓰기 작업의 비용이 늘어납니다. 그래서 자주 조회되지만 자주 바뀌지는 않는 컬럼에 인덱스를 걸고, 반대로 거의 조회되지 않거나 지나치게 자주 바뀌는 컬럼에는 인덱스를 걸지 않는 것이 일반적인 설계 원칙입니다. 무분별하게 모든 컬럼에 인덱스를 추가하면 오히려 쓰기 성능이 저하되고 저장 공간도 낭비될 수 있습니다.
PostgreSQL 같은 데이터베이스는 기본적인 B-Tree 인덱스 외에도, 부분 문자열 검색에 특화된 트라이그램 인덱스처럼 특정 목적에 맞춘 다양한 인덱스 방식을 제공합니다. 데이터의 성격과 자주 사용되는 검색 패턴에 맞는 인덱스 종류를 고르는 것이 실질적인 성능 개선으로 이어집니다.