분쇄된 필드

이 페이지에서는 MongoDB 호환성을 갖춘 Firestore에서 샤딩된 필드의 사용량을 확인하고 제어하는 방법을 설명합니다. 이 기능은 Firestore Enterprise 버전에서 사용할 수 있습니다.

문서가 작성되면 Firestore에서 특정 필드를 분쇄된 형식으로 저장해야 한다고 판단할 수 있습니다. 분할된 필드는 전체 문서 대신 필요한 필드만 읽어 쿼리 성능을 최적화합니다.

분할된 필드의 이점을 활용하는 쿼리

분쇄된 필드의 읽기는 다음 쿼리 모양에 적용됩니다(사용 가능한 경우).

  • 집계 쿼리: 집계 작업을 위해 필드의 하위 집합에만 액세스하면 되는 쿼리입니다. 예를 들면 다음과 같습니다.

    db.customers.aggregate(
      [
        { $match: { "account_balance" : { $lt : 0 } } },
        { $count: "total" }
      ]
    );
    

    또는 group-by를 사용합니다.

    db.customers.aggregate([
      { $match: { "account_balance" : { $lt : 0 } } },
      {
        $group: {
          _id: "$market_segment",
          avg_balance: { $avg: "$account_balance" }
        }
      }
    ]);
    
  • 프로젝션 쿼리: 특정 필드의 하위 집합만 반환하는 쿼리입니다. 예를 들면 다음과 같습니다.

    db.customers.find({}, { family_name: 1, given_name: 1, _id: 0 });
    
  • 필터 쿼리: Firestore 쿼리 엔진에서 문서 필터링에 잘게 썬 필드를 사용하는 것이 유익하다고 판단하는 쿼리를 필터링합니다. 예를 들면 다음과 같습니다.

    db.customers.find({ given_name: "Alice" });
    

샤딩된 필드 사용량 보기

쿼리 설명을 사용하여 쿼리에서 잘린 필드를 사용하는지 확인할 수 있습니다. 쿼리 계획의 TableScan 노드에는 다음 측정항목이 포함된 Storage 섹션이 포함됩니다.

  • 스캔 모양:
    • shredded_fields_only: 쿼리가 잘게 썬 필드에서만 읽습니다.
    • shredded_fields_backjoin: 쿼리가 분쇄된 필드에서 읽고 다른 필드의 경우 원본 문서와 조인합니다.
  • 사용된 분할 필드: 분할 필드로 읽은 속성 이름 목록입니다.
  • 다시 확인 횟수: 다시 확인을 위한 카운터의 맵입니다. 다시 확인은 잘게 썬 필드를 스캔할 때 원래 전체 문서에서 읽기로 대체하는 것을 의미합니다. 문서의 필드 값이 8KiB를 초과하는 경우 이러한 문제가 발생할 수 있습니다. 이는 잘게 썬 필드 저장소에 너무 큰 값입니다.

출력 예

...
└── • TableScan
        source: **/customers
        order: UNDEFINED
        row range: (-∞..+∞)
        filter: $lt($account_balance_1, 0)
        output bindings: {$account_balance_1=account_balance, $market_segment_1=market_segment}
        variables: [$account_balance_1, $market_segment_1]

        Execution:
         records returned: 1,374
         latency: 26.58 ms
         post-filtered rows: 13,626
         records scanned: 15,000
         data bytes read: 23.73 MiB (24,887,141 B)

        Storage:
         scan shape: shredded_fields_only
         shredded fields used: [account_balance, market_segment]

분할된 필드 사용 제어

기본적으로 MongoDB 호환성을 갖춘 Firestore는 사용할 수 있는 경우 분할된 필드를 사용합니다. 쿼리 주석의 tableScanMethod 옵션을 사용하여 이 동작을 제어할 수 있습니다.

tableScanMethod에 지원되는 값은 다음과 같습니다.

  • shreddedFieldsEnabled (기본값): 가능한 경우 분할된 필드를 사용합니다.
  • shreddedFieldsDisabled: 잘린 필드는 사용되지 않습니다.
  • forceShreddedFields: 잘린 필드를 스캔하여 테이블 스캔을 완료할 수 없는 경우 쿼리를 실패합니다.

명령어 찾기

.comment() 메서드를 사용하여 find 명령어의 옵션을 지정합니다.

db.customers.find(
  { account_balance: 0.0 }
).comment(
  {
    firestoreOptions: {
      tableScanMethod: "shreddedFieldsDisabled"
    }
  }
);

집계 명령어

aggregate 명령어의 옵션 매개변수에서 comment 옵션을 사용합니다.

db.customers.aggregate(
  [
    { $match: { "account_balance" : { $lt : 0 } } },
    { $count: "total" }
  ],
  {
    comment: {
      firestoreOptions: {
        tableScanMethod: "shreddedFieldsDisabled"
      }
    }
  }
);

쿼리 성능 경고

MongoDB 호환성을 갖춘 Firestore는 비효율적인 샤딩된 필드 사용이 감지되면 쿼리 설명 결과에 성능 경고를 표시할 수 있습니다. 예를 들면 다음과 같습니다.

  • 선택성이 낮은 쿼리: 쿼리가 필터링을 위해 분할된 필드를 스캔하지만 문서가 거의 필터링되지 않아 스캔이 비효율적입니다.

  • 재확인 횟수가 많은 쿼리: 쿼리가 전체 문서 읽기로 자주 대체되어 성능에 영향을 미칠 수 있습니다. $bsonSize와 같은 연산자를 사용하여 재확인을 트리거하는 큰 값을 식별할 수 있습니다.

이러한 경우 쿼리 옵션을 사용하여 잘게 썬 필드 읽기를 사용 중지하는 것이 좋습니다.

제한사항

Firestore는 최상위 필드만 삭제하려고 시도합니다. 또한 컬렉션당 삭제할 수 있는 필드 수를 제한합니다.