문서 메뉴
문서 홈
/
MongoDB 매뉴얼
/ /

쿼리 계획

이 페이지의 내용

  • 계획 캐시 항목 상태
  • queryHash
  • planCacheKey
  • 가용성

MongoDB 쿼리 플래너는 주어진 쿼리에 대해 사용 가능한 인덱스를 고려하여 가장 효율적인 쿼리 계획을 선택하고 캐시합니다. 쿼리 계획의 효율성을 평가하기 위해 쿼리 플래너는 평가 기간 동안 모든 후보 계획을 실행합니다. 일반적으로 평가 기간 동안 가장 적은 양의 작업을 수행하면서 가장 많은 결과를 생성하는 쿼리 계획이 채택됩니다.

관련 계획 캐시 항목은 동일한 쿼리 형태를 가진 후속 쿼리에 사용됩니다.

다음 다이어그램에서는 쿼리 플래너 로직을 보여 줍니다.

MongoDB의 쿼리 플래너 로직 다이어그램.
클릭하여 확대

참고

explain을 사용하면 기존의 모든 계획 캐시 항목이 무시되고 MongoDB 쿼리 플래너가 새 계획 캐시 항목을 만들 수 없습니다.

MongoDB 4.2부터 각 쿼리 형태는 캐시의 세 가지 상태 중 하나와 연결됩니다.

상태
설명
Missing (누락됨)

이 모양에 대한 항목이 캐시에 존재하지 않습니다.

쿼리에 대해 쿼리 형태의 캐시 항목 상태가 누락인 경우:

  1. 캐시에 해당 쿼리 형태에 대한 항목이 없거나 후보 계획이 평가되어 우승 계획이 선택되면,

  2. 캐시는 계획에 필요한 작업량을 수량화하는 값을 사용하여 비활성 상태의 쿼리 형태에 대한 항목을 생성합니다.

캐시의 항목은 이 형태에 대한 자리 표시자 항목입니다. 즉, 플래너가 도형을 보고 계획에 필요한 작업량을 수량화한 값을 계산하여 도형 자리 표시자 항목을 저장했지만 쿼리 도형은 쿼리 계획을 생성하는 데 사용되지 않습니다.

쿼리에 대해 형태의 캐시 항목 상태가 비활성인 경우:

  1. 캐시에 해당 쿼리 형태에 대한 항목이 없거나 후보 계획이 평가되어 우승 계획이 선택되면,

  2. 계획에 필요한 작업량을 수량화하는 선택된 계획의 값은 비활성 항목의 값과 비교됩니다. 선택한 계획의 값이 다음과 같은 경우입니다.

    • 보다 작거나 같은비활성 항목:

      선택된 계획은 비활성 상태의 자리 표시자 항목을 대체하고 ' 활성 상태를 갖습니다.

      교체가 발생하기 전에 비활성 항목이 활성화되면(예: 다른 쿼리 작업으로 인해) 새로 활성화된 항목은 계획에 필요한 작업량을 수량화하는 값이 선택한 계획보다 큰 경우에만 교체됩니다.

    • 비활성 항목보다 큽니다.
      비활성 항목은 그대로 유지되지만 계획에 필요한 작업량을 수량화하는 해당 값이 증가합니다.

캐시에 있는 항목은 성공적인 계획에 대한 항목입니다. 플래너는 이 항목을 사용하여 쿼리 계획을 생성할 수 있습니다.

쿼리에 대해 형태의 캐시 항목 상태가 활성인 경우:

활성 항목은 쿼리 계획을 생성하는 데 사용됩니다.

또한 플래너는 항목의 성능을 평가하고 계획에 필요한 작업량을 수량화하는 해당 값이 더 이상 선택 기준을 충족하지 않으면 비활성 상태로 전환됩니다.

계획 캐시 변경을 trigger 추가 시나리오는 계획 캐시 플러시를 참조하세요.

특정 쿼리에 대한 쿼리 계획 정보를 보려면 db.collection.explain() 또는 cursor.explain()를 사용할 수 있습니다.

컬렉션에 대한 계획 캐시 정보를 보려면 $planCacheStats 집계 단계를 사용할 수 있습니다.

mongod 가 다시 시작되거나 종료되면 쿼리 계획 캐시가 지속되지 않습니다. 또한:

  • 인덱스 또는 컬렉션 삭제와 같은 카탈로그 작업은 계획 캐시를 지웁니다.

  • 최소 사용 (LRU) 캐시 교체 메커니즘은 상태에 관계없이 가장 최근에 액세스한 캐시 항목을 지웁니다.

사용자는 또한 다음을 수행할 수 있습니다.

다음도 참조하세요.

MongoDB 5.0부터 계획 캐시는 모든 컬렉션에 대한 plan caches의 누적 크기가 0.5 GB보다 작은 경우에만 전체 plan cache 항목을 저장합니다. 모든 컬렉션에 대한 plan caches의 누적 크기가 이 임계값을 초과하면 다음 디버그 정보 없이 추가 plan cache 항목이 저장됩니다.

plan cache 항목의 예상 크기 (바이트) 는 $planCacheStats 출력에서 사용할 수 있습니다.

동일한 쿼리 형태를 가진 느린 쿼리를 식별하는 데 도움이 되도록 각 쿼리 형태는 queryHash와 연결됩니다. queryHash는 쿼리 형태의 해시를 나타내며 쿼리 형태에만 종속되는 16진수 문자열입니다.

참고

다른 해시 함수와 마찬가지로, 두 개의 다른 쿼리 형태가 동일한 해시 값을 생성할 수 있습니다. 그러나 서로 다른 쿼리 형태 간에 해시 충돌이 발생할 가능성은 거의 없습니다.

MongoDB는 쿼리 계획 캐시에 대한 더 많은 인사이트를 제공하기 위해 planCacheKey를 제공합니다.

planCacheKey 은 쿼리와 연관된 플랜 캐쉬 (plan cache) 항목에 대한 키의 해시입니다.

참고

queryHash와 달리 planCacheKey 쿼리 형태와 형태에 대해 현재 사용 가능한 색인 모두를 고려한 함수입니다. 즉, 쿼리 형태를 지원할 수 있는 인덱스를 추가 혹은 삭제되면 planCacheKey 값은 변경될 수 있지만 queryHash 값은 변경되지 않습니다.

예를 들어 다음 인덱스가 있는 컬렉션 foo 을 생각해 보겠습니다:

db.foo.createIndex( { x: 1 } )
db.foo.createIndex( { x: 1, y: 1 } )
db.foo.createIndex( { x: 1, z: 1 }, { partialFilterExpression: { x: { $gt: 10 } } } )

컬렉션에 대한 다음 쿼리는 형태가 동일합니다.

db.foo.explain().find( { x: { $gt: 5 } } ) // Query Operation 1
db.foo.explain().find( { x: { $gt: 20 } } ) // Query Operation 2

이러한 쿼리가 주어지면 부분 필터 표현식이 있는 인덱스는 쿼리 작업 2를 지원할 수 있지만 쿼리 작업 1은 지원할 수 없습니다 . 쿼리 작업 1을 지원하는 데 사용할 수 있는 인덱스가 쿼리 작업 2와 다르기 때문에 두 쿼리의 planCacheKey는 서로 다릅니다.

인덱스 중 하나가 삭제되거나 새 인덱스 { x: 1, a: 1 } 가 추가된 경우 두 쿼리 작업의 planCacheKey 값이 변경됩니다.

queryHashplanCacheKey은 다음과 같은 곳에서 사용할 수 있습니다.

인덱스 필터는 planCacheSetFilter 명령으로 설정되,며 플래너가 쿼리 형태에 대해 평가하는 인덱스를 결정합니다. 쿼리 형태는 쿼리, 정렬 및 프로젝션 사양의 조합으로 구성됩니다. 지정된 쿼리 형태에 대한 인덱스 필터가 있는 경우 플래너는 필터에 지정된 인덱스만 고려합니다.

쿼리 형태에 대한 인덱스 필터가 있는 경우, MongoDB는 hint()를 무시합니다. MongoDB가 쿼리 형태에 인덱스 필터를 적용했는지 확인하려면 indexFilterSet db.collection.explain() cursor.explain() 또는 메서드의 필드를 확인합니다.

인덱스 필터는 쿼리 플래너가 평가하는 인덱스에만 영향을 미칩니다. 즉, 플래너는 특정 쿼리 형태에 대해 여전히 컬렉션 스캔을 최적의 계획으로 선택할 수 있습니다.

이러한 인덱스 필터는 서버 프로세스가 실행되는 동안에만 유효하며, 서버가 종료되면 사라집니다 MongoDB는 사용자가 수동으로 이러한 필터를 제거할 수 있는 명령을 제공합니다.

인덱스 필터는 플래너의 기대 동작과 hint() 메서드의 작동을 변경하기 때문에, 인덱스 필터 사용은 신중하게 결정해야 합니다.

MongoDB 6.0부터 인덱스 필터는 이전에 명령을 planCacheSetFilter 사용하여 설정한 데이터 정렬을 사용합니다.

돌아가기

쓰기 성능