MongoDB의 Index에 관하여...(3) Index를 잘 사용하는 방법

YB·2024년 4월 20일

DB 공부

목록 보기
6/6

과도한 Indexing의 부작용

  • Indexing을 하면 쿼리 조회 시간을 줄여주지만, 삽입/삭제/수정 작업 시마다 Index 데이터에도 변경이 필요하기 때문에 부하가 늘어남

  • Index의 크기가 MongoDB에 할당된 RAM 의 크기를 넘게 되어 Disk(SSD, HDD)에까지 Index를 저장하게 되면, 작업 속도가 느려질 수 있음

    • MongoDB가 할당하는 RAM 용량 계산 방법(Default 값)
      (1) (호스트 머신의 RAM 용량 - 1GB) / 2
      (2) (1)의 값이 256MB보다 작은 경우 : 256MB

    • 특정 콜렉션의 인덱스 크기를 구하는 방법
      (1) 호스트 머신에서 mongod 콘솔 접속
      (2) var stats = db.{콜렉션}.stats({indexDetails:true}) 입력
      (3) stats.indexDetails 결과로 나온 정보 중 ‘cache’의 ‘bytes currently in the cache’ 확인


explain() 함수

  • 쿼리의 수행 내역을 알려줌
  • 사용 방법 예시

    db.getCollection("testCollection01").find({}).explain()

  • 결과: 엄청 긺 (공식 설명 페이지)
    "explainVersion" : "2",
    "queryPlanner" : {
        "namespace" : "testDB.testCollection01",
        "indexFilterSet" : false,
        "parsedQuery" : {

        },
        "queryHash" : "E475932B",
        "planCacheKey" : "E9553396",
        "maxIndexedOrSolutionsReached" : false,
        "maxIndexedAndSolutionsReached" : false,
        "maxScansToExplodeReached" : false,
        "winningPlan" : {
            "queryPlan" : {
                "stage" : "COLLSCAN",
                "planNodeId" : 1.0,
                "filter" : {

                },
                "direction" : "forward"
            },
            "slotBasedPlan" : {
                "slots" : "$$RESULT=s4 env: { s2 = Nothing (SEARCH_META), s1 = TimeZoneDatabase(Pacific/Niue...MST7MDT) (timeZoneDB), s3 = 1713606949659 (NOW) }",
                "stages" : "[1] scan s4 s5 none none none none lowPriority [] @\"d0048750-113c-4499-93f2-141020126166\" true false "
            }
        },
        "rejectedPlans" : [

        ]
    },
    "command" : {
        "find" : "testCollection01",
        "filter" : {

        },
        "$db" : "testDB"
    },
    "serverInfo" : {
        "host" : "DESKTOP-U9HQ4VK",
        "port" : 27017.0,
        "version" : "7.0.3",
        "gitVersion" : "b96efb7e0cf6134d5938de8a94c37cec3f22cff4"
    },
    "serverParameters" : {
        "internalQueryFacetBufferSizeBytes" : 104857600.0,
        "internalQueryFacetMaxOutputDocSizeBytes" : 104857600.0,
        "internalLookupStageIntermediateDocumentMaxSizeBytes" : 104857600.0,
        "internalDocumentSourceGroupMaxMemoryBytes" : 104857600.0,
        "internalQueryMaxBlockingSortMemoryUsageBytes" : 104857600.0,
        "internalQueryProhibitBlockingMergeOnMongoS" : 0.0,
        "internalQueryMaxAddToSetBytes" : 104857600.0,
        "internalDocumentSourceSetWindowFieldsMaxMemoryBytes" : 104857600.0,
        "internalQueryFrameworkControl" : "trySbeEngine"
    },
    "ok" : 1.0
}

hint() 함수

  • 쿼리를 수행할 때 해당 인덱스를 사용하도록 강제함
  • 사용 방법 예시
    • testCollection01에 있는 데이터를 전부 출력할건데, size 인덱스를 활용함

      db.getCollection("testCollection01").find({}).hint({size: 1}).explain();

  • 참고
    • db.collection.getIndexes() 를 사용해서 현재 걸려있는 Index를 확인할 수 있음
    • db.users.find().hint( { $natural : 1 } ) 이렇게 $natural 키워드를 사용하면, Index를 사용하지 않고 그냥 앞에서부터 스캔하도록 강제할 수 있음(비교용)

참고:

profile
뭐라도 만들어본다

0개의 댓글