MongoDB에서 쿼리 성능을 분석하거나 최적화할 때는 explain() 메서드를 활용하여 쿼리 실행 계획(query plan)을 확인할 수 있습니다. explain()은 해당 쿼리가 어떤 방식으로 실행되는지, 인덱스를 사용하는지 아니면 전체 컬렉션을 스캔하는지 등의 상세 정보를 보여줍니다.
1. 샘플 컬렉션 생성
먼저 문서를 포함한 컬렉션을 생성해 보겠습니다.
> db.demo202.insertOne({"StudentFirstName":"Chris","StudentAge":21});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e3c3bd103d395bdc21346e8")
}
> db.demo202.insertOne({"StudentFirstName":"David","StudentAge":23});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e3c3bd803d395bdc21346e9")
}
> db.demo202.insertOne({"StudentFirstName":"Bob","StudentAge":22});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e3c3bde03d395bdc21346ea")
}2. find()로 전체 문서 조회하기
find() 메서드를 사용하면 컬렉션에 저장된 모든 문서를 화면에 표시할 수 있습니다.
> db.demo202.find();
위 쿼리를 실행하면 다음과 같은 결과가 출력됩니다.
{ "_id" : ObjectId("5e3c3bd103d395bdc21346e8"), "StudentFirstName" : "Chris", "StudentAge" : 21 }
{ "_id" : ObjectId("5e3c3bd803d395bdc21346e9"), "StudentFirstName" : "David", "StudentAge" : 23 }
{ "_id" : ObjectId("5e3c3bde03d395bdc21346ea"), "StudentFirstName" : "Bob", "StudentAge" : 22 }3. explain()으로 쿼리 실행 계획 확인하기
이제 explain() 메서드를 사용하여 특정 쿼리의 실행 계획을 확인해 보겠습니다. find() 결과에 .explain()을 연결하기만 하면 됩니다.
> db.demo202.find({"StudentFirstName":"David"}).explain();실행하면 아래와 같은 상세 출력 결과를 얻을 수 있습니다.
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.demo202",
"indexFilterSet" : false,
"parsedQuery" : {
"StudentFirstName" : {
"$eq" : "David"
}
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"StudentFirstName" : {
"$eq" : "David"
}
},
"direction" : "forward"
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "DESKTOP-QN2RB3H",
"port" : 27017,
"version" : "4.0.5",
"gitVersion" : "3739429dd92b92d1b0ab120911a23d50bf03c412"
},
"ok" : 1
}주요 필드 해석
- winningPlan.stage: "COLLSCAN" — 컬렉션 스캔(Collection Scan)을 의미합니다. 즉, 이 쿼리는 인덱스 없이 컬렉션의 모든 문서를 처음부터 끝까지 훑으며 조건에 맞는 문서를 찾았습니다.
- parsedQuery — MongoDB가 실제로 파싱한 쿼리 조건($eq: David)을 보여줍니다.
- indexFilterSet: false — 인덱스 필터가 적용되지 않았음을 나타냅니다.
- rejectedPlans — 채택되지 않은 대안 실행 계획 목록입니다. 여기서는 빈 배열입니다.
COLLSCAN이 표시된다면 데이터 양이 많아질 경우 성능 저하가 발생할 수 있으므로, 자주 조회되는 필드에 인덱스를 생성하는 것이 좋습니다. 인덱스를 추가한 후 다시 explain()을 실행하면 stage가 IXSCAN으로 변경되어 인덱스가 활용되고 있음을 확인할 수 있습니다.