CodeGym /행동 /SQL SELF /주요 인덱스 종류: B-TREE, HASH, GIN, GiST

주요 인덱스 종류: B-TREE, HASH, GIN, GiST

SQL SELF
레벨 37, 레슨 1
사용 가능

자, PostgreSQL 세계에는 여러 가지 인덱스가 있고, 각각 자기만의 역할이 있어. 이건 마치 교통수단 고르는 거랑 비슷해. 공원 산책할 땐 자전거가 좋지만, 도시 반대편 갈 땐 차를 타겠지? 인덱스도 마찬가지로, 상황에 따라 맞는 걸 골라야 해.

PostgreSQL에서 주요 인덱스 종류는 다음과 같아:

  • B-TREE 인덱스: 대부분의 상황에 쓸 수 있는 범용 인덱스.
  • HASH 인덱스: 정확한 값 비교에 최적화됨.
  • GIN 인덱스: 배열이나 JSONB 검색에 딱임.
  • GiST 인덱스: 지리 정보 같은 복잡한 데이터 타입에 사용됨.

인덱스는 행 검색을 빠르게 하려고 만들어진 거야. 최적화 방식이 4가지나 있는데, 각 타입마다 특정 작업에 더 빠르고, 특정 데이터 타입에 더 잘 맞아.

인덱스를 직접 관리할 수는 없어. 네가 할 수 있는 건 인덱스 타입을 고르는 것뿐이야: 아예 안 쓰거나, 위에 나온 것 중 하나를 쓰거나. 이제 각각을 하나씩 파보자. 언제, 어떻게 써야 하는지 감 잡을 수 있을 거야.

B-TREE 인덱스

B-TREE (balanced tree의 줄임말)는 PostgreSQL에서 제일 많이 쓰이는 인덱스야. 이 인덱스는 트리 구조로 데이터를 정리해서, 검색이나 정렬, 필터링을 빠르게 해줘.

도서관 책장이 있다고 생각해봐. 각 책장에는 책이 가나다순으로 정렬돼 있어. "ㅁ"으로 시작하는 책을 찾으려면 모든 책을 다 볼 필요 없이, 중간부터 시작하면 돼. B-TREE도 이런 원리로 동작해.

언제 쓰면 좋을까?

거의 항상! B-TREE 인덱스는 특히 이런 데 좋아:

  • 범위 검색: WHERE price > 100
  • 정렬: ORDER BY name ASC
  • 정확한 값 검색: WHERE id = 42

예시로 만들어보자:

-- products 테이블의 price 컬럼에 B-TREE 인덱스 생성:
CREATE INDEX idx_price ON products(price);

이제 WHERE price > 100 같은 쿼리를 쓰면, PostgreSQL이 이 인덱스를 활용해서 전체 테이블을 다 뒤지지 않아도 돼.

HASH 인덱스

HASH 인덱스는 해시 테이블을 써서 빠르게 값을 찾는 방식이야. 정확히 일치하는 값 비교에 강점이 있어. 하지만 HASH 인덱스는 범위 검색이나 정렬은 지원하지 않아.

이건 마치 도서관 카드 파일에서, 각 카드에 번호가 딱 붙어 있는 거랑 비슷해. 42번 카드를 찾으라고 하면 바로 찾아주지만, "40번부터 50번까지 보여줘"라고 하면 못 해줘.

HASH 인덱스는 오직 정확한 값 검색에만 써:

  • WHERE email = 'user@example.com'
  • SELECT ... WHERE id = 123

범위나 정렬이 필요하면 HASH는 안 맞아.

생성 예시:

-- users 테이블의 email 컬럼에 해시 인덱스 생성:
CREATE INDEX idx_email_hash ON users USING HASH (email);

이제 PostgreSQL은 WHERE email = 'user@example.com' 같은 쿼리에 이 인덱스를 쓸 거야.

참고: HASH 인덱스는 특정 상황에서만 쓰이고, B-TREE보다 덜 자주 사용돼.

GIN 인덱스 (Generalized Inverted Index)

GIN은 배열, JSONB, 텍스트 데이터에 진짜 마법을 부리는 특수 인덱스야. 수천 개의 서랍이 있는 캐비닛을 상상해봐. 각 서랍엔 라벨이 붙어 있고, "사과" 서랍엔 사과만, "바나나" 서랍엔 바나나만 들어 있어. 사과나 바나나를 찾으려면 모든 서랍을 뒤질 필요 없이 바로 해당 서랍으로 가면 돼.

GIN 인덱스는 이런 데 필요해:

  • 배열 검색: @> (포함), <@ (포함됨)
  • JSONB 데이터: WHERE jsonb_data @> '{"key": "value"}'

생성 예시

-- 배열을 담고 있는 products 테이블의 tags 컬럼에 GIN 인덱스 생성:
CREATE INDEX idx_tags_gin ON products USING GIN (tags);

이제 PostgreSQL은 "전자제품"이나 "추천" 같은 태그가 들어간 상품을 빠르게 찾을 수 있어.

GiST 인덱스 (Generalized Search Tree)

GiST 인덱스는 지리 좌표나 범위 같은 복잡한 데이터 타입에 강력한 도구야. 공간 검색이나 범위 검색에 최적화된 트리를 만들어줘.

도시 지도를 생각해봐. 각 지점이 좌표로 표시돼 있고, 현재 위치에서 반경 5km 안에 있는 모든 지점을 빠르게 찾을 수 있어.

GiST는 이런 데 좋아:

  • 지리 데이터: SELECT ... FROM locations WHERE ST_DWithin(geom, point, distance)
  • 범위 검색: WHERE date_range && '[2023-01-01, 2023-12-31]'

예시:

-- 지리 데이터를 담고 있는 places 테이블의 location 컬럼에 GiST 인덱스 생성:
CREATE INDEX idx_location_gist ON places USING GiST (location);

이제 가까운 지점을 찾는 등 복잡한 지리 쿼리를 할 수 있어.

인덱스 비교 표

인덱스 타입 적합한 용도 사용 예시 비고
B-TREE 범위 검색, 정렬 price > 100, ORDER BY name ASC 범용 인덱스.
HASH 정확한 값 비교 email = 'user@example.com', id = 42 범위 검색 불가.
GIN 배열, JSONB tags @> '{tech}', jsonb_data @> '{"key": "value"}' 복잡한 데이터에 더 빠름.
GiST 지리, 범위, 거리 ST_DWithin(geom, point, distance) 지리 데이터에 사용.

이제 PostgreSQL의 주요 인덱스 타입과 그 활용법을 알게 됐어. 인덱스 선택은 전략적인 한 수야. 쿼리 속도가 여기서 갈리거든. 체스에서 체크메이트 치듯, 느린 쿼리도 끝!

2
과제
SQL SELF, 레벨 37, 레슨 1
잠금
데이터 정렬 속도를 높이기 위한 `B-TREE` 인덱스 생성
데이터 정렬 속도를 높이기 위한 `B-TREE` 인덱스 생성
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION