Database/Postgresql

GiST와 GIN 인덱스

kyoulho 2024. 8. 15. 16:36

PostgreSQL은 다양한 데이터 구조와 검색 요구에 대응할 수 있는 인덱싱 시스템을 제공한다. 그중에서도 GiST(Generalized Search Tree)와 GIN(Generalized Inverted Index)은 데이터의 구조와 검색 방식에 따라 최적화된 두 가지 주요 인덱스 유형이다.
 

GiST (Generalized Search Tree)

범위 쿼리, 공간 데이터, 사용자 정의 데이터 타입 등 다양한 데이터 구조에 대해 유연한 인덱싱을 제공하는 트리 기반 인덱스이다. B-트리와 유사한 구조를 가지고 있으며, 특정 데이터 타입이나 쿼리 조건에 맞춰 쉽게 확장할 수 있다.

구조 및 특성

  • 트리 구조: GiST 인덱스는 B-트리와 유사하게 각 노드가 키와 자식 노드 포인터를 포함하는 트리 구조를 가진다.
  • 범위 및 근사 쿼리: GiST는 범위 쿼리나 근사 검색(예: 공간 데이터의 범위 내 검색)에서 뛰어난 성능을 발휘한다.
  • 확장성: 사용자 정의 데이터 타입과 연산자 클래스의 지원을 통해 다양한 도메인에 맞춤화된 인덱스를 구현할 수 있다.
  • 부분 인덱스 지원: 특정 조건을 만족하는 데이터만 인덱싱하여 인덱스 크기를 줄이고 성능을 향상시킬 수 있다.
  • 업데이트 성능: GiST는 삽입 및 업데이트 작업에서 비교적 빠른 성능을 보인다.

사용 사례

  • 공간 데이터: 지리적 좌표, 다각형 등의 지리적 데이터를 처리하는 데 적합하다.
  • 범위 및 근사 검색: 날짜나 숫자 범위, 근사 일치 검색이 필요한 경우 유리하다.
  • 커스텀 데이터 타입: 사용자 정의 데이터 타입에 대한 인덱스 구현에 적합하다.

 

GIN (Generalized Inverted Index)

다중 값 데이터 타입(예: 배열, JSONB)에 대해 효율적인 검색을 제공하는 인덱스이다. 각 고유 값을 키로 하여 값이 포함된 모든 레코드를 빠르게 찾을 수 있는 역 인덱스 구조를 가진다.

구조 및 특성

  • 역 인덱스 구조: GIN은 단일 값을 키로 하는 역 인덱스 구조를 가지며, 값이 나타나는 모든 레코드를 추적한다. 이로 인해 특정 값의 포함 여부를 매우 빠르게 확인할 수 있다.
  • 트리와 해시의 혼합: GIN 인덱스는 트리 구조와 해시 구조를 혼합하여 고수준의 검색과 포함 여부를 빠르게 확인한다.
  • 다중 값 데이터 검색: 배열이나 JSONB 데이터에서 특정 값의 포함 여부를 빠르게 확인할 수 있다.
  • 압축 기능: 포스팅 리스트 압축을 통해 인덱스 크기를 줄이고 메모리 사용량을 최적화한다.
  • Fast Update 기술: GIN은 Fast Update 기술을 통해 인덱스 업데이트 성능을 개선한다.
  • 다중 컬럼 인덱스: 여러 컬럼에 대한 복합 인덱스를 지원하여 복잡한 쿼리에서도 효율적인 검색이 가능하다.

사용 사례

  • 배열 데이터: 배열 필드에서 특정 값의 포함 여부를 빠르게 검색한다.
  • JSONB 데이터: JSONB 데이터에서 키-값 쌍에 대한 효율적인 검색을 지원한다.
  • 다중 값 필드: 태그 목록 등 다중 값 필드에서 빠른 검색이 필요한 경우 적합하다.

역인덱스 구조의 개념

역인덱스는 문서나 레코드 내에서 찾고자 하는 키워드이 어떤 문서레코드에 위치하고 있는지를 나타내는 매핑을 제공한다. 기본적으로 두 가지 주요 구성 요소가 있다:

  1. 용어 사전(Term Dictionary): 검색하고자 하는 각 고유 값(키)를 저장하는 테이블. 이 테이블은 데이터베이스 내의 각 고유 값에 대해 하나의 엔트리를 가진다.
  2. 포스팅 리스트(Posting List): 각 고유 값에 해당하는 레코드나 문서 ID 목록. 이 리스트는 해당 값이 포함된 모든 레코드나 문서의 ID를 저장한다.

역인덱스 구조의 예시

예를 들어, 다음과 같은 간단한 데이터가 있다고 가정하자.

레코드 1: "apple banana cherry"
레코드 2: "banana cherry"
레코드 3: "apple banana"

이 데이터를 바탕으로 역인덱스를 생성하면 다음과 같이 구성된다.

용어 사전                포스팅 리스트
----------               ----------------
"apple"   --------->   [레코드 1, 레코드 3]
"banana"  --------->   [레코드 1, 레코드 2, 레코드 3]
"cherry"  --------->   [레코드 1, 레코드 2]

역인덱스의 구조적 특징

  • 효율적인 검색: 역인덱스는 특정 값을 포함하는 레코드를 매우 빠르게 찾을 수 있다. 예를 들어, "banana"를 검색하면 곧바로 레코드 1, 2, 3을 반환할 수 있다.
  • 포스팅 리스트 압축: GIN 인덱스에서 포스팅 리스트는 압축될 수 있다. 이는 중복된 데이터나 큰 데이터셋에서 메모리 사용을 최적화하는 데 유용하다.
  • 다중 값 처리: 역인덱스는 배열이나 JSONB 같은 다중 값 필드에서 각 값을 개별적으로 인덱싱하여, 어떤 레코드가 특정 값을 포함하는지 빠르게 확인할 수 있다.

 
 

GiST vs GIN 비교 요약

  • 데이터 구조: GiST는 범위 및 근사 검색에 유리한 트리 기반 구조를 가지며, GIN은 다중 값 데이터의 검색을 최적화한 역 인덱스 구조를 사용한다.
  • 검색 성능: GiST는 복잡한 쿼리와 범위 검색에 강점이 있으며, GIN은 배열이나 JSONB 같은 다중 값 데이터에 대해 더 나은 성능을 제공한다.
  • 메모리 사용량 및 인덱스 크기: GIN은 GiST보다 메모리 사용량이 많고, 인덱스 크기가 크다. 특히 고유 값이 많을수록 이 차이는 커진다.
  • 업데이트 성능: GiST는 GIN보다 일반적으로 업데이트 성능이 우수하다.
  • 쿼리 유형에 따른 선택: 범위 검색이나 복잡한 데이터 타입에는 GiST가, 정확한 일치 검색이나 포함 검색에는 GIN이 더 적합하다.

'Database > Postgresql' 카테고리의 다른 글

PostgreSQL 초기 설정  (0) 2023.08.25