쿼리 성능 최적화

느린 쿼리 문제를 해결하려면 Query Explain을 사용하여 쿼리 실행 계획과 런타임 실행 프로필을 가져옵니다. 다음 섹션에서는 실행 프로필에 따라 쿼리 성능을 최적화하기 위해 취할 수 있는 단계를 설명합니다.

결과 수 제한

실행 트리에서 반환된 레코드 필드를 사용하여 쿼리가 많은 문서를 반환하는지 확인합니다. limit(...) 단계를 사용하여 반환되는 문서 수를 제한하는 것이 좋습니다. 이렇게 하면 네트워크를 통해 클라이언트에 반환될 때 결과의 직렬화된 바이트 크기가 줄어듭니다. Limit 노드 앞에 MajorSort 노드가 있는 경우 쿼리 엔진은 LimitMajorSort 노드를 병합하고 전체 인메모리 구체화 및 정렬을 TopN 정렬로 대체하여 쿼리의 메모리 요구사항을 줄일 수 있습니다.

결과 문서 크기 제한

select(...)를 사용하여 필요한 필드만 반환하거나 remove_fields(...)를 사용하여 너무 큰 필드를 삭제하여 반환되는 문서의 크기를 제한하는 것이 좋습니다. 이렇게 하면 중간 결과 처리의 컴퓨팅 및 메모리 비용과 네트워크를 통해 클라이언트에 반환될 때 결과의 직렬화된 바이트 크기를 줄일 수 있습니다. 쿼리에서 참조되는 모든 필드가 일반 색인으로 처리되는 경우 쿼리가 색인 검색으로 완전히 처리되어 기본 스토리지에서 문서를 가져올 필요가 없습니다.

색인 사용

다음 안내에 따라 색인을 설정하고 최적화하세요.

쿼리에서 색인을 사용하고 있는지 확인

실행 트리의 리프 노드를 확인하여 쿼리에서 색인을 사용하고 있는지 확인할 수 있습니다. 실행 트리의 리프 노드가 TableScan 노드인 경우 쿼리가 색인을 사용하지 않고 기본 스토리지에서 문서를 스캔하고 있음을 의미합니다. 색인이 사용 중인 경우 실행 트리의 리프 노드에 색인의 색인 ID와 색인 필드가 표시됩니다.

더 나은 색인 식별

색인은 쿼리 엔진이 기본 스토리지에서 가져와야 하는 문서 수를 줄일 수 있거나 필드 순서가 쿼리의 정렬 요구사항을 충족할 수 있는 경우 쿼리에 유용합니다.

쿼리에 색인이 사용되지만 쿼리 엔진이 여전히 많은 문서를 가져와서 삭제하는 경우(많은 레코드를 반환하는 스캔 노드와 적은 레코드를 반환하는 필터 노드로 식별됨) 색인을 사용하여 충족된 쿼리 조건자가 선택적이지 않다는 신호입니다. 더 적합한 색인을 만들려면 색인 만들기를 참고하세요.

쿼리에 색인이 사용되지만 쿼리 엔진이 여전히 쿼리 실행 트리의 MajorSort 노드로 식별되는 결과 집합의 메모리 내 재정렬을 실행하는 경우, 이는 사용된 색인이 쿼리의 정렬 요구사항을 제공하는 데 사용될 수 없다는 신호입니다. 더 적합한 색인을 만들려면 다음 섹션을 참고하세요.

색인 만들기

색인 관리 문서를 따라 색인을 만듭니다. 쿼리에서 색인을 사용할 수 있도록 하려면 다음 순서로 필드가 있는 일반(멀티 키 아님) 색인을 만드세요.

  1. 등호 연산자에 사용될 모든 필드입니다. 쿼리 간 재사용 가능성을 극대화하려면 쿼리 간 등호 연산자에서 필드가 발생하는 빈도의 내림차순으로 필드를 정렬합니다.
  2. 정렬할 모든 필드(동일한 순서)입니다.
  3. 범위 또는 부등호 연산자에 사용될 필드입니다(쿼리 제약 조건 선택성의 내림차순).
  4. 색인의 쿼리 일부로 반환될 필드: 색인에 이러한 필드를 포함하면 색인이 쿼리를 처리하고 기본 스토리지에서 문서를 가져오지 않아도 됩니다.

색인 또는 테이블 스캔 강제 실행

네이티브 모드에서 Firestore를 쿼리하면 쿼리 효율을 높일 수 있는 모든 색인이 자동으로 사용됩니다. 따라서 쿼리에 색인을 지정할 필요가 없습니다. 하지만 워크로드에 중요한 쿼리의 경우 보다 일관된 성능을 위해 forceIndex 옵션을 사용하는 것이 좋습니다.

일부 경우에는 기본 모드의 Firestore가 선택한 색인으로 인해 쿼리 지연 시간이 증가할 수도 있습니다. 성능 회귀 문제 해결 단계를 따르고 쿼리에 다른 색인을 시도하는 것이 적절한지 확인한 경우 forceIndex 옵션을 사용하여 색인을 지정할 수 있습니다.

파이프라인 작업의 모든 입력 단계에서 forceIndex 옵션을 사용하여 Native 모드의 Firestore 기본 쿼리 계획을 재정의하고 사용할 색인을 지정하거나 테이블 스캔을 강제할 수 있습니다.

특정 색인 강제 적용

쿼리에서 특정 색인을 사용하도록 강제하려면 색인 ID를 문자열로 forceIndex 옵션에 제공합니다. 콘솔 또는 오류 메시지에서 색인 ID를 확인할 수 있습니다.

다음 예에서는 플래너가 ID가 CICAgOi36pgK인 색인을 사용하도록 강제합니다.

// Force Planner to use Index ID CICAgOi36pgK
db.pipeline()
  .collectionGroup({ collectionId: "customers", forceIndex: "CICAgOi36pgK" })
  .limit(100)

특정 인덱스를 강제하는 몇 가지 사용 사례는 다음과 같습니다.

  • 다양한 색인의 실적을 테스트합니다.
  • 특정 알려진 최적 색인이 쿼리에 사용되도록 합니다.
  • 기본 선택이 특정 쿼리에 최적화되지 않은 경우 최적화 도구를 재정의합니다.

지정된 색인을 찾을 수 없으면 쿼리가 실패합니다.

테이블 스캔 강제 실행

테이블 스캔은 보조 색인을 사용하지 않고 컬렉션 또는 컬렉션 그룹의 문서를 읽습니다. 테이블 스캔을 강제 실행하려면 forceIndexprimary로 설정합니다.

다음 예시에서는 테이블 검색을 강제합니다.

// Force Planner to only do a Full-Table Scan
db.pipeline()
  .collectionGroup({ collectionId: "customers", forceIndex: "primary" })
  .limit(100)

다음과 같은 경우 테이블 스캔을 사용할 수 있습니다.

  • 색인 오버헤드가 정당화되지 않는 매우 작은 컬렉션의 경우
  • 컬렉션의 대부분의 문서에 액세스하는 쿼리
  • 디버깅 및 성능 비교용입니다.

Query Explain과 함께 forceIndex 사용

Query Explain을 특히 analyze 옵션과 함께 사용하여 forceIndex의 효과를 관찰할 수 있습니다.

  • 실행 트리의 리프 노드에서 색인 ID를 확인하여 기본 모드의 Firestore가 forceIndex에서 지정된 색인을 사용했는지 확인합니다.
  • forceIndex: "primary"를 사용할 때 TableScan 노드가 계획에 표시되는지 확인합니다.
  • forceIndex를 사용하거나 사용하지 않고 지연 시간, 스캔된 문서, 스캔된 색인 항목과 같은 성능 측정항목을 비교하여 쿼리 성능을 미세 조정합니다.

forceIndex 관련 권장사항

forceIndex를 사용하면 쿼리 실행을 더 세부적으로 제어할 수 있지만 일반적으로 네이티브 모드의 Firestore 쿼리 최적화 도구는 대부분의 사용 사례에서 효율적입니다. forceIndex를 사용할 때는 다음 권장사항을 고려하세요.

  • forceIndex를 신중하게 사용하세요. 기본 쿼리 계획의 성능이 최적이 아닌 경우 Query Explain을 사용하여 문제를 진단한 후 색인을 강제 적용하세요.
  • forceIndex를 사용하는 경우 실제 데이터 볼륨으로 쿼리를 테스트하여 성능 및 비용 특성을 파악해야 합니다.
  • 프로덕션 환경의 대규모 컬렉션에서는 forceIndex: "primary"를 사용하지 마세요.