문서 메뉴
문서 홈
/
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, 모든 collection에 대한 plan caches 의 누적 크기가 0 보다 작은 경우에만 계획 캐시 가 전체 plan cache 항목을 저장합니다.5 GB. 모든 collection에 대한 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 사용하여 설정한 데이터 정렬을 사용합니다.

← 쓰기 작업 성능