인덱스 종류 - B-Tree, 해시, full-text, Spatial

2025년 05월 01일 by __admin

인덱스 종류에는 어떤 것들이 있을까요? MySQL은 다양한 종류의 인덱스를 제공하며, 데이터의 특성과 쿼리 유형에 따라 적합한 인덱스를 선택하는 것이 중요합니다. 또한, 사용하는 스토리지 엔진(예: InnoDB, MyISAM)에 따라 지원하는 인덱스 종류가 다를 수 있습니다. 가장 대표적인 인덱스 종류는 다음과 같습니다.

 

B-Tree 인덱스 (Balanced Tree Index)

가장 일반적이고 널리 사용되는 인덱스 유형입니다. MySQL의 기본 스토리지 엔진인 InnoDB와 MyISAM 모두 B-Tree 기반의 인덱스를 기본으로 사용합니다. 이름처럼 균형 잡힌 트리(Balanced Tree) 구조로 데이터를 저장합니다. 루트(Root) 노드에서 시작하여 중간(Branch) 노드를 거쳐 최종 데이터 포인터가 있는 리프(Leaf) 노드까지 계층적인 탐색을 통해 데이터를 찾습니다. 항상 균형을 유지하므로 어떤 값을 검색하든 비슷한 처리 속도를 보장합니다.

 

다양한 비교 연산에 효율적입니다.

  1. 등호(=): 특정 값을 정확히 찾는 데 빠릅니다.
  2. 부등호(>, <, >=, <=): 값의 범위를 검색하는 데 효율적입니다.
  3. BETWEEN: 특정 범위 내의 값을 찾는 데 사용됩니다.
  4. LIKE 'prefix%': 값의 앞부분이 일치하는 경우(%가 뒤에 오는 경우) 인덱스를 활용할 수 있습니다. (단, LIKE '%text' 나 LIKE '%text%' 처럼 %가 앞에 오면 인덱스를 타기 어렵습니다.)
  1. 대부분의 경우 B-Tree 인덱스가 좋은 성능을 제공하므로 가장 먼저 고려하게 되는 인덱스입니다.

 

해시 인덱스 (Hash Index)

키(Key) 값을 해시 함수(Hash Function)를 통해 계산된 해시 값으로 변환하고, 이 해시 값을 기반으로 데이터 위치를 찾는 방식입니다. 마치 사전을 찾을 때 단어의 첫 글자로 바로 해당 페이지로 넘어가는 것과 비슷합니다. 오직 등호(=) 또는 IN 연산자를 사용한 정확한 값 검색에만 최적화되어 있습니다. 해시 값은 순서나 크기 개념이 없기 때문에 부등호(>, <)를 이용한 범위 검색이나 ORDER BY를 이용한 정렬에는 사용할 수 없습니다. 매우 빠른 검색 속도: 해시 충돌이 없는 이상, 거의 O(1)에 가까운 매우 빠른 검색 속도를 보입니다. MEMORY 스토리지 엔진에서 주로 사용하며, 사용자가 직접 해시 인덱스를 생성할 수 있습니다. (InnoDB는 내부적으로 'Adaptive Hash Index'라는 기능을 사용하여 자주 접근되는 데이터에 대해 메모리 내에 해시 인덱스를 구축하지만, 사용자가 InnoDB 테이블에 직접 해시 인덱스를 생성할 수는 없습니다.) 범위 검색 불가, 정렬 작업에 활용 불가, 전체 인덱스 스캔 불가 등의 단점이 있습니다.

 

전문 인덱스 (Full-Text Index)

텍스트 데이터(예: 기사 본문, 상품 설명 등)의 내용을 기반으로 특정 단어나 구문을 빠르게 검색하기 위한 인덱스입니다. 일반적인 B-Tree 인덱스는 텍스트 전체를 인덱싱하기에는 비효율적입니다. 자연어 검색(Natural Language Search)에 특화되어 있으며, MATCH() ... AGAINST() 구문을 사용하여 검색합니다. InnoDB와 MyISAM 스토리지 엔진에서 지원합니다. 텍스트 검색이 빈번한 게시판, 블로그, 상품 검색 기능 등에 유용하게 사용됩니다.

 

공간 인덱스 (Spatial Index)

위도, 경도와 같은 공간 데이터 타입(Point, Line, Polygon 등)을 효율적으로 처리하기 위한 인덱스입니다. R-Tree 알고리즘을 기반으로 구현되는 경우가 많습니다. 특정 위치 주변의 장소를 찾거나, 특정 영역 안에 포함된 지점을 찾는 등 지리 정보 시스템(GIS) 관련 쿼리에 사용됩니다. 대부분의 스토리지 엔진에서 지원합니다.

 

클러스터형 인덱스 vs 비클러스터형 인덱스 (InnoDB 기준)

InnoDB 스토리지 엔진을 이해하는 데 매우 중요한 개념입니다.

클러스터형 인덱스 (Clustered Index)

테이블당 하나만 존재할 수 있으며, 보통 **기본 키(Primary Key)**가 클러스터형 인덱스로 지정됩니다. 인덱스의 리프 노드가 실제 데이터 행 자체를 포함하고 있습니다. 즉, 테이블 데이터가 기본 키 순서대로 물리적으로 정렬되어 저장됩니다. 기본 키 검색 시 성능이 매우 빠르지만, 기본 키가 아닌 컬럼으로 검색할 때는 비클러스터형 인덱스를 거쳐야 합니다. 기본 키가 없는 경우, InnoDB는 내부적으로 고유한 NOT NULL 컬럼이나 자동으로 생성된 6바이트 ID를 클러스터형 인덱스로 사용합니다.

 

비클러스터형 인덱스 (Non-Clustered Index / Secondary Index)

테이블당 여러 개 생성할 수 있습니다. (예: user_name 컬럼, email 컬럼 등에 각각 생성) 인덱스의 리프 노드에는 **인덱스로 지정된 컬럼의 값과 해당 데이터의 클러스터형 인덱스 키(기본 키 값)**가 저장됩니다. 비클러스터형 인덱스를 통해 데이터를 찾을 때는, 먼저 해당 인덱스에서 기본 키 값을 찾은 다음, 이 기본 키 값을 이용해 클러스터형 인덱스를 다시 검색하여 최종 데이터 행을 가져옵니다. (추가적인 검색 단계 발생)

 

어떤 인덱스를 선택해야 할까?

  1. 대부분의 경우 B-Tree 인덱스가 좋은 선택입니다.
  2. 정확한 값 매칭만 필요하고 범위 검색이나 정렬이 필요 없다면 해시 인덱스를 고려할 수 있습니다 (주로 MEMORY 엔진).
  3. 텍스트 내용 검색이 필요하다면 전문 인덱스를 사용합니다.
  4. 위치 기반 데이터 검색에는 공간 인덱스를 사용합니다.
  5. InnoDB에서는 기본 키 선택이 클러스터형 인덱스 구조와 성능에 큰 영향을 미치므로 신중하게 설계해야 합니다.

이제 다양한 인덱스의 종류에 대해 알아보았습니다. 다음으로는 실제로 MySQL에서 인덱스를 어떻게 생성하고, 조회하고, 삭제하는지에 대한 구체적인 SQL 문법을 살펴보겠습니다.