인덱스·쿼리 최적화 (Indexes)¶
개요¶
컬렉션이 커지면 "원하는 문서를 빨리 찾는" 일이 중요해져요. MongoDB에서 인덱스(index)는 쿼리의 효율적 실행을 지원하는 역할을 해요. 인덱스가 없으면 MongoDB는 쿼리 결과를 돌려주기 위해 컬렉션의 모든 문서를 스캔해야 해요. 적절한 인덱스가 있으면 그 인덱스가 스캔해야 할 문서의 수를 크게 줄여 쿼리를 빠르게 만들어요.
다만 인덱스는 공짜가 아니에요. 인덱스가 조회 성능을 높이지만 쓰기에는 부담을 줘요. 문서를 삽입(insert)할 때마다 해당 컬렉션의 인덱스도 함께 갱신해야 하기 때문이에요. 그래서 쓰기가 많은 컬렉션에서는 인덱스를 아껴 쓰는 게 좋아요.
핵심 개념¶
인덱스는 B-tree 구조¶
인덱스는 컬렉션 데이터의 일부를 쉽게 탐색할 수 있는 형태로 저장하는 특별한 자료구조예요. MongoDB 인덱스는 B-tree를 사용해요. 인덱스는 특정 필드(또는 필드 집합)의 값을 그 값으로 정렬해 저장하므로, 동등 비교(equality)와 범위 검색(range)을 효율적으로 지원하고, 정렬된 결과도 인덱스 순서를 그대로 써서 돌려줄 수 있어요.
기본 _id 인덱스¶
컬렉션이 생성될 때 MongoDB는 _id 필드에 유니크 인덱스를 자동으로 만들어요. 이 인덱스가 클라이언트가 같은 _id 값을 가진 문서를 두 개 넣지 못하게 막아요. 즉 _id의 유일성을 보장하는 게 바로 이 기본 인덱스예요.
인덱스 타입¶
- 단일 필드 인덱스 (Single Field) — 하나의 필드에 거는 기본형 인덱스예요. 직원 ID로 자주 조회하는 경우처럼 단일 필드 검색을 빠르게 해요.
- 복합 인덱스 (Compound) — 여러 필드를 묶어 하나의 인덱스로 만들어요. 예를 들어
item과quantity두 필드를 함께 검색하는 경우 둘을 묶은 인덱스가 효과적이에요. 필드 순서가 검색 조건과 맞아야 해요. - 멀티키 인덱스 (Multikey) — 배열 필드에 거는 인덱스예요. 배열의 각 요소가 인덱스 항목이 돼서 "이 값이 포함된 문서"를 찾는 쿼리를 지원해요.
- 지리공간 인덱스 (Geospatial) — 위치 기반 검색을 지원하는 인덱스예요.
인덱스 이름¶
인덱스의 기본 이름은 인덱스에 쓴 키와 각 키의 방향(1/-1)을 밑줄로 이어 붙여요. 예를 들어 { item: 1, quantity: -1 } 인덱스의 이름은 item_1_quantity_-1이 돼요. 한번 만든 인덱스는 이름을 바꿀 수 없고, 새 이름으로 다시 만들려면 삭제(drop) 후 재생성해야 해요.
실제 적용 (데이터스케쳐스)¶
문서형 저장소를 쓸 때도 인덱스 설계는 곧 쿼리 성능이에요.
_id기본 인덱스 — 모든 문서를 식별하는 기본 키로 자동 유니크 인덱스가 붙어요.- 자주 조회하는 필드에 단일 인덱스 — 콘텐츠를 조회하는 기준이 되는 필드(작성자, 상태 등)에 단일 필드 인덱스를 걸어요.
- 복합 인덱스로 검색 조건 맞추기 — "이 테넌트의 상태가 공개된 문서"처럼 여러 조건으로 자주 찾는 경우, 그 조건을 묶은 복합 인덱스로 스캔 범위를 줄여요.
- 멀티키로 배열 검색 — 캔버스의 태그·참여자 배열을 자주 검색한다면 멀티키 인덱스로 "이 태그가 달린 문서"를 빠르게 찾아요.
인덱스는 조회를 빠르게 하지만 쓰기 부담을 키운다는 점을 잊지 말아요. 쓰기가 잦은 컬렉션에는 꼭 필요한 인덱스만 아껴 두는 게 좋아요. PostgreSQL의 인덱스 원리와 크게 다르지 않아요.
더 알아보기¶
- 공식 문서 (1차)
- 인덱스 (Indexes) — mongodb.com/docs/manual/indexes
- 인덱스 타입 — mongodb.com/docs/manual/core/indexes/index-types
- 인덱스 전략 — mongodb.com/docs/manual/applications/indexes
- 유니크 인덱스 — mongodb.com/docs/manual/core/index-unique
- 큐레이션/블로그 (2차)
- MongoDB 공식 블로그 — mongodb.com/blog