본문으로 건너뛰기
김신건의 로그

[DB] GIN / GiST / Hash / BRIN: 비-B-tree 인덱스

· 수정 · 📖 약 1분 · 457자/단어 #postgresql #index #gin #gist #brin #database
GIN, GiST, SP-GiST, BRIN, Hash index, pg_trgm, JSONB 인덱스, full-text index

정의

B-tree 외 PostgreSQL 의 특수 인덱스 들. 자세한 B-tree 는 btree-indexing 참고.

인덱스적합
B-tree= < > BETWEEN ORDER BY (default)
Hash=
GIN다값 (배열, JSONB, full-text)
GiST공간, 범위, 유사도
SP-GiST공간 partitioning (Quadtree, kd-tree)
BRIN큰 시계열, 잘 정렬된 데이터
Bloom다컬럼 동등성 (확률)

GIN (Generalized Inverted Index)

하나의 컬럼이 여러 값 인 경우 (배열, JSONB, tsvector).

CREATE INDEX idx_tags ON posts USING gin(tags);
SELECT * FROM posts WHERE tags @> ARRAY['ruby', 'rails'];   -- 빠름

CREATE INDEX idx_jsonb ON events USING gin(payload jsonb_path_ops);
SELECT * FROM events WHERE payload @> '{"type": "click"}';

CREATE INDEX idx_fts ON articles USING gin(to_tsvector('english', body));
SELECT * FROM articles WHERE to_tsvector('english', body) @@ to_tsquery('postgres');
flowchart LR
    Doc1["doc 1: [a, b, c]"] --> Inv["a → [doc1, doc3]<br/>b → [doc1, doc2]<br/>c → [doc1]"]
    Doc2["doc 2: [b, d]"]
    Doc3["doc 3: [a, e]"]
    Inv --> Q["query: contains 'a' → [doc1, doc3]"]

TIP

JSONB 의 가장 흔한 인덱스. @>, ?, ?&, ?| 연산자 가속.

GiST (Generalized Search Tree)

tree 구조의 일반화. 공간 + 범위 + 유사도 검색.

-- PostGIS 공간
CREATE INDEX idx_geom ON places USING gist(geom);
SELECT * FROM places WHERE ST_DWithin(geom, ST_Point(-122, 37), 1000);

-- 범위 타입
CREATE INDEX idx_range ON bookings USING gist(during);
SELECT * FROM bookings WHERE during && '[2026-06-25, 2026-06-26)'::tsrange;

-- pg_trgm 유사도
CREATE EXTENSION pg_trgm;
CREATE INDEX idx_name_trgm ON users USING gist(name gist_trgm_ops);
SELECT * FROM users WHERE name % 'koa';   -- 유사 매치

BRIN (Block Range Index)

큰 테이블 + 물리 순서 ≈ 논리 순서 일 때. block 의 min/max 만 저장.

CREATE INDEX idx_created ON events USING brin(created_at);
SELECT * FROM events WHERE created_at >= '2026-06-25';
B-treeBRIN
크기큼 (~ 10% of table)작음 (~0.01%)
정밀도정확대략 (block range)
적합일반시계열, append-only

IMPORTANT

수억 row 의 시계열 에서 BRIN 이 B-tree 의 1/100 메모리. 단 INSERT 순서와 정렬 컬럼이 일치 해야 효과.

Hash Index

CREATE INDEX idx_email_hash ON users USING hash(email);
SELECT * FROM users WHERE email = 'koa@x.com';   -- 빠름
SELECT * FROM users WHERE email LIKE 'koa%';     -- 사용 안 됨
  • = 검색만. range 불가.
  • PostgreSQL 10+ 부터 WAL 지원 (이전엔 replication 안 됨).
  • B-tree 가 거의 항상 더 좋음. 극히 큰 컬럼= 만 검색 일 때 약간 우위.

SP-GiST

-- IP 주소 등 partitioning 자연
CREATE INDEX idx_ip ON logs USING spgist(client_ip);

Quadtree, kd-tree, radix treegeneric 으로 구현. 비균등 분포 데이터에 강함.

Bloom Index

CREATE EXTENSION bloom;
CREATE INDEX idx_multi ON events USING bloom(user_id, type, source)
  WITH (length = 80, col1 = 4, col2 = 4, col3 = 4);

SELECT * FROM events WHERE user_id = 42 AND type = 'click';
  • 다컬럼 동등성.
  • 확률적: false positive 가능 (PG 가 재검증).
  • 모든 컬럼 동시 조회 에서 큰 B-tree 다수 대신.

인덱스 선택 매트릭스

flowchart TD
    Q1{쿼리 유형?}
    Q1 -->|"= < > BETWEEN ORDER BY"| Btree[B-tree]
    Q1 -->|"="| Hash[B-tree 또는 Hash]
    Q1 -->|배열 / JSONB / FTS| GIN[GIN]
    Q1 -->|공간 / 범위 / 유사도| GiST[GiST]
    Q1 -->|시계열 큼 + 정렬| BRIN[BRIN]
    Q1 -->|다컬럼 = AND| Bloom[Bloom 또는 B-tree composite]
    Q1 -->|IP / 비균등| SPGist[SP-GiST]

인덱스 크기 비교 (1억 row)

1억 row, 인덱스 종류별 크기 (직관)
BRIN 이 압도적으로 작음. GIN 은 다값이라 크다.

흔한 함정

WARNING

  1. JSONB 에 B-tree 인덱스 = 잘못. GIN 으로.
  2. 모든 컬럼에 인덱스 = INSERT 폭증. 사용 안 되는 인덱스 pg_stat_user_indexes.idx_scan = 0 으로 식별.
  3. BRIN + 무작위 insert = 효과 0. clustered insert 가 전제.
  4. hash index 의존 = 옛 버전은 WAL 안됨 → replica 에 없음. PG 10+ 만.

관련 위키

이 글의 용어 (4개)
[DB Internals] B-Tree와 B+Tree 인덱싱database-internals
정의 B-Tree (B+ Tree) 는 거의 모든 RDB 의 인덱스 자료구조. balanced tree, 디스크 I/O 최소화 설계. 특징: - 균형 (balanced): 모든 …
[DB] EXPLAIN 읽기: scan, join, sort, costdatabase-internals
정의 EXPLAIN = 쿼리 실행 계획 표시. EXPLAIN ANALYZE = 실제로 실행 + 실제 시간 측정. Scan 종류 | Scan | 의미 | 적합 | |---|---|…
[DB] PostgreSQL: 프로세스 모델, MVCC, WAL, 확장성database-internals
정의 PostgreSQL 은 오픈소스 ORDBMS. 1986 UC Berkeley POSTGRES 의 후예. MVCC, 확장 가능 타입, JSONB, full-text searc…
[Redis] Vector Search: HNSW, SVS-VAMANA, Semantic Cachedatabase-internals
정의 Vector Search 는 임베딩 벡터의 거리/유사도 기준으로 근접한 K 개 를 찾는 검색. Redis 는 RediSearch 모듈 (Redis 8 부터는 코어) 과 Va…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기