Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 아키텍쳐 개선
- ipo 매매자동화
- gRPC
- 디버깅
- 구현
- jwt 표준
- AWS
- 레디스 동시성
- langgraph
- 완전탐색
- JPA
- 이분탐색
- ai agent
- 백준
- 크롤링
- 쿠키
- 셀러리
- 추천 검색 기능
- piplining
- 검색어 추천
- next-stock
- 카카오
- 트랜잭샨
- spring event
- 프로그래머스
- 누적합
- docker
- BFS
- 몽고 인덱스
- 결제서비스
Archives
- Today
- Total
코딩관계론
MongoDB 쿼리 성능 이슈 및 인덱스 최적화 과정 본문
반응형
대규모 데이터 배치 작업 후, 검색 쿼리 성능이 현저히 저하되는 문제가 발생했습니다. 특히 특정 쿼리 수행 시간이 약 4초에 달했습니다.
1. 쿼리 실행 계획 분석
성능 저하 원인을 분석하기 위해 MongoDB의 쿼리 실행 계획을 확인했습니다.
db.news.find({'stockCode': '437730', 'isRelated': true}).explain("executionStats")
결과:
- stage:
COLLSCAN
→ 전체 컬렉션을 풀 스캔했습니다. - totalDocsExamined: 102,457 → 약 10만 건의 문서를 모두 검사했습니다.
- nReturned: 8 → 최종 반환된 문서 수는 8건입니다.
- executionTimeMillis: 3,374ms → 쿼리 한 번에 3초 이상 소요됐습니다.
결국, 인덱스가 없어 전체 데이터를 모두 스캔해 성능 저하가 발생한 것으로 확인됐습니다.
2. 인덱스 설계를 통한 성능 개선
MongoDB는 B-Tree 기반 인덱스를 사용하며, 주요 인덱스 유형은 다음과 같습니다.
- 단일 인덱스: 한 필드에 대한 인덱스 (예:
{ stockCode: 1 }
) - 복합 인덱스: 여러 필드를 조합한 인덱스 (예:
{ stockCode: 1, isRelated: 1, isThema: 1 }
) - 멀티키 인덱스: 배열 필드에 자동 생성되는 인덱스
2.1 복합 인덱스의 선두 필드 중요성
복합 인덱스에서 선두 필드 배치는 성능에 큰 영향을 미칩니다.
- 예시 (효율적):
(stockCode, isRelated, isThema)
{
"executionTimeMillis": 0,
"totalKeysExamined": 8,
"totalDocsExamined": 8,
"stage": "FETCH",
"inputStage": {
"stage": "IXSCAN",
"keyPattern": {"stockCode": 1, "isRelated": 1, "isThema": 1}
}
}
- 예시 (비효율적):
(isRelated, stockCode, isThema)
{
"executionSuccess": true,
"nReturned": 8,
"executionTimeMillis": 3374,
"totalKeysExamined": 0,
"totalDocsExamined": 102457,
"executionStages": {
"stage": "COLLSCAN",
"filter": {"stockCode": "437730"}
}
}
이유:
MongoDB는 B-Tree 인덱스 구조상 선두 필드를 기준으로 검색합니다. 선두 필드를 포함하지 않은 쿼리는 인덱스 효율성이 떨어져 결국 풀 스캔을 하게 됩니다.
3. Partial Index와 Sparse Index 활용
MongoDB는 특정 조건의 문서만 인덱싱하는 기능을 제공합니다.
- Partial Index: 특정 조건을 만족하는 문서만 인덱싱
- Sparse Index: 필드가 없는 문서는 제외
Partial Index 예시:
db.news.createIndex(
{ stockCode: 1, isRelated: 1, isThema: 1 },
{ partialFilterExpression: { isRelated: true } }
);
이를 통해 불필요한 인덱스 크기와 업데이트 부담을 줄일 수 있지만, 해당 조건 외의 쿼리는 여전히 풀 스캔이 발생할 수 있어 주의가 필요합니다.
4. 최종 성능 개선 결과
복합 인덱스와 Partial Index를 활용하여 쿼리 성능을 최적화한 결과, 실행 시간이 수 초에서 1ms 미만으로 극적으로 개선됐습니다.
{
"executionSuccess": true,
"nReturned": 8,
"executionTimeMillis": 0,
"totalKeysExamined": 8,
"totalDocsExamined": 8,
"stage": "FETCH",
"inputStage": {
"stage": "IXSCAN",
"indexName": "stockCode_1_isRelated_1_isThema_1",
"isPartial": true
}
}
🎯 결론 및 핵심 포인트
- 데이터 배치 후 성능 저하는 인덱스 부재나 설계 오류가 원인일 가능성이 높습니다.
- MongoDB 복합 인덱스는 선두 필드(leading field)의 배치가 성능을 좌우합니다.
explain("executionStats")
로 쿼리 실행 방식을 정확히 분석할 수 있습니다.- 필요에 따라 Partial Index와 Sparse Index를 적절히 활용해 인덱스 크기와 쓰기 부담을 관리해야 합니다.
최종적으로 쿼리 성능을 3초에서 1ms로 약 99%의 성능 향상 효과를 달성했습니다.
반응형
'개발 > Hot-Stock' 카테고리의 다른 글
수익화를 위한 쇼 - (에드센스) (0) | 2025.02.24 |
---|---|
사담 (0) | 2025.02.22 |
컨슈머 랙을 줄이기 위해서 파티션을 늘렸더니 동시성 이슈가 발생해버렸다 (1) | 2025.02.06 |
RAG를 활용한 주식 테마 관련 뉴스 필터링 (0) | 2025.01.29 |
크롤링 IP 제한 문제 해결: 서버리스 아키텍처 도입 (0) | 2025.01.21 |