이 장에서는 몽고디비 쿼리 성능 분석을 소개합니다. SQL의 explain과 유사하게, 몽고디비도 쿼리 문의 성능을 분석하는 explain을 지원합니다.
기본 사용법
explain 함수를 호출하여 분석 결과를 얻을 수 있습니다.
// find 메서드의 분석 결과
db.collection.find({}).explain();
// aggregate 메서드의 분석 결과
db.collection.explain().aggregate([]);
explain에는 세 가지 모드가 있습니다:
- queryPlanner (기본값)
- executionStats
- allPlansExecution
설명:
- queryPlanner를 사용하면 모든 가능한 실행 계획을 나열하고 실제 문을 실행하지 않으며 이미 이긴 winningPlan 계획을 표시합니다.
- executionStats를 사용하면 이긴 winningPlan 계획만 실행하고 결과를 출력합니다.
- allPlansExecution을 사용하면 모든 계획을 실행하고 결과를 출력합니다.
다른 모드의 사용법
// executionStats 모드, 단순히 explain 함수에 매개변수를 전달
db.collection.find({}).explain('executionStats');
// allPlansExecution 모드
db.collection.find({}).explain('allPlansExecution');
explain 내용 설명
queryPlanner 내용
explain으로 반환되는 기본 내용은 다음과 같습니다.
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.orders",
"indexFilterSet" : false, // 키 메트릭, 인덱스 필터링 데이터를 사용하는지 여부
"winningPlan" : {
"stage" : "COLLSCAN", // 키 메트릭, 단계 이름. 각 단계에는 단계별 정보가 있으며 COLLSCAN은 전체 컬렉션 콘텐츠를 스캔하는 것을 나타냅니다
"direction" : "forward"
},
"rejectedPlans" : [ ]
}
...
}
단계 유형은 다음과 같습니다:
- COLLSCAN: 전체 테이블 스캔
- IXSCAN: 인덱스 스캔
- FETCH: 인덱스를 기반으로 특정 문서를 검색
- SHARD_MERGE: 각 샤드가 반환한 데이터 병합
- SORT: 메모리에서 정렬을 나타냄
- LIMIT: 반환되는 수를 제한
- SKIP: 사용하지 않고 건너뛰기
- IDHACK: _id에 대한 쿼리
- SHARDING_FILTER: 몽고스를 통해 조각화된 데이터 조회
- COUNT: db.coll.explain().count() 또는 유사한 카운트 작업에 사용되는 단계 반환
- COUNTSCAN: 카운트에 인덱스를 사용하지 않고 카운트하는 경우의 단계 반환
- COUNT_SCAN: 카운트에 인덱스를 사용하여 카운트하는 경우의 단계 반환
- SUBPLA: $or 쿼리에 인덱스를 사용하지 않고 단계 반환
- TEXT: 전체 텍스트 인덱스를 사용하여 조회하는 경우의 단계 반환
- PROJECTION: 반환되는 필드를 제한하는 단계 반환
executionStats 내용
executionStats 모드에서 반환되는 내용은 다음과 같습니다.
{
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 5, // 반환된 문서 수
"executionTimeMillis" : 0, // 실행 시간
"totalKeysExamined" : 0, // 스캔된 인덱스 수
"totalDocsExamined" : 5, // 스캔된 문서의 총 수
"executionStages" : {
"stage" : "COLLS CAN", // 단계 유형, COLLSCAN은 전체 테이블을 스캔하는 것을 의미합니다
"nReturned" : 5,
"executionTimeMillisEstimate" : 0,
"works" : 7,
"advanced" : 5,
"needTime" : 1,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"direction" : "forward",
"docsExamined" : 5
}
}
}
쿼리 최적화 아이디어
- 가능한 한 인덱스를 사용
- 스캔하는 문서 수를 줄일수록 좋습니다