MongoDB Covered Index 이해하기
대규모 데이터 환경에서 쿼리 성능을 최적화하는 핵심 기술 중 하나는 Covered Index(Index-only Query) 를 활용하는 것이다. Covered Index는 쿼리 처리에 필요한 모든 정보가 인덱스 안에 포함되어 있어 Document 본문을 읽을 필요가 없는 경우를 의미한다.
즉, Disk I/O 없이 인덱스만으로 결과를 반환할 수 있어 속도와 리소스 효율성이 매우 뛰어나다.
1. Covered Index란 무엇인가?
MongoDB에서 쿼리가 Covered Index가 되기 위한 조건은 다음과 같다:
- 필터 조건이 인덱스 필드에 포함되어야 한다. find()의 where 조건 필드가 인덱스에 존재해야함
- Projection 필드와 인덱스 필드가 일치해야 한다. 반환해야 하는 필드가 전부 인덱스에 포함되어야 한다.
- _id를 제외해야 하는 경우가 많다. _id는 자동 포함되므로 필요 없으면 _id:0 명시
- 정렬을 사용하는 경우 정렬 필드도 인덱스 사용, sort 대상 또한 인덱스 안에 있어야 fetch 발생이 없다.
Fetch 발생하는 경우
IXSCAN → FETCH → PROJECTION
중간에 FETCH가 있으면 문서를 읽은 것 → Covered Index가 아님.
진짜 Covered 라면
IXSCAN → PROJECTION_COVERED
여기에서 explain 결과가 "totalDocsExamined": 0 나온다.
2. 인덱스 생성 예시
db.movies.createIndex(
{ type: 1, genres: 1, year: -1, title: 1 },
{
name: "type_genres_year_title_movieOnly",
partialFilterExpression: { type: "movie" }
}
);
Partial Index를 사용하는 경우
- 인덱스 크기 감소 - 전체 문서 중에 type : movie 만 포함시킨다.
- 선택도 향상 - 불필요한 값이 포함되지 않는다.
- 스캔 범위 축소 가능 - 쿼리 최적화 가능

3. Covered Index를 활용하는 쿼리 예시
Non Covered Index 적용 시
db.movies.find(
{ type: "movie", genres: "Drama" }
).sort({ year: -1 });

db.movies.find(
{ type: "movie", genres: "Drama" },
{ title: 1, year: 1, _id: 0 }
).sort({ year: -1 });

결과 Explain Plan

IXSCAN -> PROJECTION_COVERED
totalDocsExamined: 0
Document Fetch 없이 인덱스만으로 결과 처리 가능
Sort도 인덱스로 해결 -> in-memory sort가 없다.
4. Projection이 왜 중요한가?
아래 예시는 Covered Index가 깨지는 경우:
db.movies.find(
{ type: "movie", genres: "Drama" },
{ title: 1, year: 1, rated: 1, _id: 0 }
)
- rated 필드가 인덱스에 없다. 이러면 결국 본문에서 읽어야 한다.
- 결과적으로 fetch 발생하게 된다. -> covered 불가
5. Covered Index 활용 가능한 케이스들
- Projection Covered -> find, project, sort 를 같이한다.
- index-only distinct -> db.movies.distinct("genres") 인덱스 포함시
- count 최적화 -> count()가 인덱스로만 가능
- index intersection (제한) -> 여러 인덱스 조합
6. Covered 여부 확인 checklist
- explain("executionStats") 결과 확인 가능
"totalDocsExamined": 0
"totalKeysExamined": N
"stage": "PROJECTION_COVERED"
Explain Tree 예시
PROJECTION_COVERED (4ms)
└── IXSCAN (7ms)
7. 정리
| 기능 | 비-covered | covered(Index-only) |
| I/O 비용 | 높음 | 낮음 |
| 응답성능 | 느림 | 대부분 빠름 |
| 필드 요구사항 | 제한 없음 | 필드가 모두 인덱스에 존재해야함 |
Covered Index는 MongoDB 성능 최적화의 핵심 기술이며,
특히 대용량 조회 API, 검색 리스트 화면, 정렬 포함 목록 페이징, 통계 조회 등에서 큰 효과를 볼 수 있겠다.
'IT' 카테고리의 다른 글
| 바이브 코딩 잘 활용하기 (0) | 2025.12.25 |
|---|---|
| Spring AOP로 Controller 파라미터 자동 주입하기 (0) | 2025.11.16 |
| [대규모 시스템 설계 기초] 10장. 알림 시스템 설계 (0) | 2025.11.09 |
| [대규모 시스템 설계 기초] 4장. 처리율 제한 장치의설계 - 3 (0) | 2025.11.02 |
| [대규모 시스템 설계 기초] 4장. 처리율 제한 장치의설계 - 2 (0) | 2025.10.19 |
댓글
이 글 공유하기
다른 글
-
바이브 코딩 잘 활용하기
바이브 코딩 잘 활용하기
2025.12.25 -
Spring AOP로 Controller 파라미터 자동 주입하기
Spring AOP로 Controller 파라미터 자동 주입하기
2025.11.16 -
[대규모 시스템 설계 기초] 10장. 알림 시스템 설계
[대규모 시스템 설계 기초] 10장. 알림 시스템 설계
2025.11.09 -
[대규모 시스템 설계 기초] 4장. 처리율 제한 장치의설계 - 3
[대규모 시스템 설계 기초] 4장. 처리율 제한 장치의설계 - 3
2025.11.02