Computer >> 컴퓨터 >  >> 프로그래밍 >> MongoDB

MongoDB 대규모 동적 데이터셋에서 태그 집계 성능 시스템 구축하는 방법

MongoDB에서 대규모 동적 데이터셋의 태그를 효율적으로 처리하려면 인덱스 생성explain() 분석이 핵심입니다. 배열 필드에 인덱스를 만들면 멀티키(multikey) 인덱스로 동작하여 $in 연산자 기반의 태그 검색 성능을 크게 향상시킬 수 있습니다.

1단계: 인덱스 생성 및 샘플 데이터 준비

먼저 컬렉션에 인덱스를 생성한 뒤, 태그 역할을 할 배열 필드가 포함된 문서들을 삽입합니다.

> db.demo278.ensureIndex({"Subjects":1});
{
    "createdCollectionAutomatically" : true,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}
> db.demo278.insertOne({"Subjects":["MySQL","MongoDB","Java"]});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e49096edd099650a5401a55")
}
> db.demo278.insertOne({"Subjects":["C","C++"]});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e490978dd099650a5401a56")
}
> db.demo278.insertOne({"Subjects":["Spring","Hibernate"]});
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e490984dd099650a5401a57")
}

2단계: 저장된 문서 확인

find() 메서드를 사용해 컬렉션의 모든 문서를 조회합니다.

> db.demo278.find();

위 쿼리는 다음과 같은 결과를 출력합니다.

{ "_id" : ObjectId("5e49096edd099650a5401a55"), "Subjects" : [ "MySQL", "MongoDB", "Java" ] }
{ "_id" : ObjectId("5e490978dd099650a5401a56"), "Subjects" : [ "C", "C++" ] }
{ "_id" : ObjectId("5e490984dd099650a5401a57"), "Subjects" : [ "Spring", "Hibernate" ] }

3단계: explain()으로 쿼리 성능 검증

$in 연산자로 여러 태그를 동시에 조회하는 쿼리의 실행 계획을 explain()으로 확인합니다.

> db.demo278.find({Subjects:{$in:["Spring","MongoDB"]}}).explain();

실행 결과는 다음과 같습니다.

{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "test.demo278",
        "indexFilterSet" : false,
        "parsedQuery" : {
            "Subjects" : {
                "$in" : [
                    "MongoDB",
                    "Spring"
                ]
            }
        },
        "winningPlan" : {
            "stage" : "FETCH",
            "inputStage" : {
                "stage" : "IXSCAN",
                "keyPattern" : {
                    "Subjects" : 1
                },
                "indexName" : "Subjects_1",
                "isMultiKey" : true,
                "multiKeyPaths" : {
                    "Subjects" : [
                        "Subjects"
                    ]
                },
                "isUnique" : false,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 2,
                "direction" : "forward",
                "indexBounds" : {
                    "Subjects" : [
                        "[\"MongoDB\", \"MongoDB\"]",
                        "[\"Spring\", \"Spring\"]"
                    ]
                }
            }
        },
        "rejectedPlans" : [ ]
    },
    "serverInfo" : {
        "host" : "DESKTOP-QN2RB3H",
        "port" : 27017,
        "version" : "4.0.5",
        "gitVersion" : "3739429dd92b92d1b0ab120911a23d50bf03c412"
    },
    "ok" : 1
}

결과 해석

실행 계획에서 주목할 부분은 다음과 같습니다.

IXSCAN 단계: winningPlan의 inputStage가 IXSCAN(인덱스 스캔)으로 표시되므로, 컬렉션 전체를 훑는 COLLSCAN이 아닌 인덱스를 활용한 효율적인 조회가 이루어졌습니다.

isMultiKey: true: Subjects 필드가 배열이기 때문에 MongoDB가 자동으로 멀티키 인덱스를 적용했습니다. 덕분에 배열 내 개별 요소 각각이 인덱스 항목으로 등록되어 태그 검색이 빠르게 처리됩니다.

indexBounds: ["MongoDB", "MongoDB"]와 ["Spring", "Spring"] 범위로 좁혀진 것을 볼 수 있습니다. 즉, $in 조건의 각 값이 정확한 인덱스 경계로 변환되어 불필요한 스캔 없이 해당 태그만 조회됩니다.

이처럼 배열 필드에 인덱스를 생성하고 explain()으로 IXSCAN 사용 여부를 확인하는 것이 대규모 동적 데이터셋에서 태그 집계 성능을 확보하는 기본 전략입니다. 참고로 ensureIndex()는 현재 deprecated되었으므로, MongoDB 4.2 이상 환경에서는 createIndex()를 사용하는 것이 좋습니다.