인덱스 (B-tree·부분·표현식·GIN)¶
개요¶
테이블이 커질수록 "원하는 행을 빨리 찾는" 일이 중요해져요. 인덱스(index)는 그걸 돕는 별도 구조로, 데이터베이스가 특정 행을 인덱스 없이 찾는 것보다 훨씬 빠르게 찾아내게 해줍니다. PostgreSQL 공식 문서는 인덱스란 "서버가 특정 행을 훨씬 빠르게 찾고 가져오도록 해주는 흔한 성능 향상 수단"이라고 설명해요.
다만 인덱스는 성능을 무료로 주는 게 아니에요. 쓰기(UPDATE·INSERT·DELETE)할 때 인덱스도 함께 갱신해야 하니 전체 시스템에 부담을 더합니다. 그래서 문서는 "현명하게(sensibly) 써야 한다"고 강조해요. 무작정 많이 만드는 것보다, 어떤 쿼리에 어떤 인덱스가 맞는지를 아는 게 중요해요.
핵심 개념¶
인덱스 타입 — 언제 어떤 걸¶
PostgreSQL은 여러 인덱스 타입을 제공하는데, 상황에 따라 골라 씁니다.
- B-tree — PostgreSQL의 기본 인덱스예요. 정렬 가능한 데이터의 동등 비교(=)와 범위 비교(<, >, BETWEEN)에 최적이에요. 특별한 이유가 없으면 대부분 이걸 씁니다.
- Hash — 동등 비교(=)만 빠르게 처리할 때 쓰는 인덱스예요. 범위 검색은 못 해요.
- GIN (Generalized Inverted Index) — 한 행 안에 여러 값이 들어 있는 데이터, 예를 들어 배열이나 JSONB 문서의 항목을 검색할 때 강력해요. 항목 하나하나를 역색인으로 만들어 빠르게 찾아요.
- GiST / SP-GiST / BRIN — 기하 데이터나 대량 정렬 데이터 등 특수한 경우에 쓰는 인덱스예요. 우리가 주로 쓰는 범위 밖이라 여기서는 이름만 짚고 넘어갈게요.
부분 인덱스 (Partial Index)¶
일부 행만 인덱스로 만들 수 있어요. 예를 들어 "상태가 활성(active)인 행만" 인덱스를 만든다면, 활성 행이 전체에서 일부일 때 인덱스를 훨씬 작게 유지할 수 있어요. 작은 인덱스는 저장 공간도 적게 쓰고 갱신 부담도 줄어요. WHERE 절이 항상 그 조건을 포함하는 쿼리를 빠르게 하려는 때 잘 맞아요.
표현식 인덱스 (Expression Index)¶
컬럼 값 그대로가 아니라, 컬럼에 어떤 표현식(식)을 적용한 결과를 기준으로 인덱스를 만들 수 있어요. 예를 들어 소문자로 바꾼 값(lower(email))을 인덱스로 만들면, 대소문자 구분 없이 이메일을 찾는 쿼리가 빠져요. 단, 쿼리가 인덱스에 쓴 것과 같은 표현식을 써야 인덱스를 활용한다는 점을 기억하세요.
멀티컬럼·유니크·인덱스 전용 스캔¶
- 멀티컬럼 인덱스 — 여러 컬럼을 묶어 인덱스를 만들 수 있어요. 컬럼 순서가 검색 조건과 맞을 때 효과적이에요.
- 유니크 인덱스 — 중복 값을 허용하지 않게 해줘요. 기본 키·유일 제약의 바탕이 돼요.
- 인덱스 전용 스캔(Index-Only Scan) — 쿼리가 필요한 값이 전부 인덱스에 들어 있으면, 테이블 행을 굳이 읽지 않고 인덱스만으로 답할 수 있어요. 이때 visibility map(VACUUM이 관리)이 힘을 써요.
사용 사례 / 실제 적용¶
- 기본 조회는 B-tree — 사용자 ID, 이메일, 시간 범위처럼 정렬·범위 검색이 잦은 컬럼은 B-tree 인덱스를 기본으로 걸어요.
- 부분 인덱스로 작고 빠르게 — "active 상태의 테넌트만"처럼 전체의 일부만 자주 조회되는 경우, 그 조건으로 부분 인덱스를 만들어 인덱스 크기와 쓰기 부담을 줄여요.
- 표현식 인덱스로 검색 패턴 맞추기 —
lower(email)처럼 쿼리가 매번 변환을 적용해 찾는 경우, 그 변환을 인덱스로 만들어 쿼리가 인덱스를 타게 해요. - GIN으로 배열·JSONB 검색 — 태그 배열이나 JSONB 문서의 항목을 자주 검색한다면 GIN 인덱스를 만들어, "이 값이 포함된 문서"를 빠르게 찾아요.
더 알아보기¶
- 공식 문서 (1차)
- 인덱스 (Indexes) — postgresql.org/docs/current/indexes.html
- 인덱스 타입 — postgresql.org/docs/current/indexes-types.html
- 부분 인덱스 — postgresql.org/docs/current/indexes-partial.html
- 표현식 인덱스 — postgresql.org/docs/current/indexes-expressional.html
- 큐레이션/블로그 (2차)
- PostgreSQL 인덱스 튜닝 팁 모음 — use-the-index-luke.com