シュレッドされたフィールド

このページでは、Cloud Firestore でシュレッド フィールドの使用状況を表示して制御する方法について説明します。これは Firestore Enterprise エディションで利用できます。

ドキュメントが書き込まれると、Cloud Firestore は特定のフィールドをシュレッド形式で保存する必要があると判断する場合があります。シュレッドされたフィールドは、ドキュメント全体ではなく必要なフィールドのみを読み取ることで、クエリのパフォーマンスを最適化します。

シュレッド フィールドのメリットを享受できるクエリ

シュレッドされたフィールドの読み取りは、該当する場合、次のクエリ形状に適用されます。

  • 集計クエリ: 集計オペレーションでフィールドのサブセットにのみアクセスする必要があるクエリ。例:

    db.pipeline()
      .collection("/customers")
      .where(lessThan("account_balance", 0))
      .aggregate(
        countAll().as("total"),
      )
    

    または group-by を使用します。

    db.pipeline()
      .collection("/customers")
      .where(lessThan("account_balance", 0))
      .aggregate({
        accumulators: [
          field('account_balance').average().as('avg_account_balance')
        ],
        groups: [field('market_segment')]
      })
    
  • 射影クエリ: 特定のフィールドのサブセットのみを返すクエリ。例:

    db.pipeline()
      .collection("/customers")
      .select("family_name", "given_name")
      .limit(10)
    
  • フィルタ クエリ: Cloud Firestore クエリエンジンが、ドキュメント フィルタリングにシュレッド フィールドを使用することが有益であると判断したクエリ。例:

    db.pipeline()
      .collection("/customers")
      .where(equal("given_name", "alice"))
    

シュレッドされたフィールドの使用状況を表示する

クエリがシュレッド フィールドを使用しているかどうかを確認するには、クエリの説明を使用します。クエリプランの TableScan ノードには、次の指標を含む Storage セクションが含まれます。

  • スキャン形状:
    • shredded_fields_only: クエリはシュレッドされたフィールドからのみ読み取ります。
    • shredded_fields_backjoin: クエリは、シュレッドされたフィールドから読み取り、他のフィールドの元のドキュメントと結合します。
  • 使用されたシュレッド フィールド: シュレッド フィールドとして読み取られたフィールド名のリスト。
  • 再チェック数: 再チェックのカウンタのマップ。再チェックとは、シュレッドされたフィールドをスキャンするときに、元の完全なドキュメントからの読み取りに戻ることを意味します。これは、ドキュメントのフィールド値が 8 KiB を超えている場合に発生することがあります。これは、シュレッド フィールドのストレージとしては大きすぎます。

出力例

...
└── • TableScan
        source: /customers
        order: UNDEFINED
        row range: (-∞..+∞)
        filter: ($account_balance_1 < 0L)
        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]

シュレッドされたフィールドの使用を制御する

デフォルトでは、Cloud Firestore は使用可能な場合にシュレッド フィールドを使用します。この動作は、table_scan_method クエリ オプションを使用して制御できます。

table_scan_method オプションでサポートされている値は次のとおりです。

  • shredded_fields_enabled(デフォルト): 利用可能な場合は、シュレッドされたフィールドを使用します。
  • shredded_fields_disabled: シュレッド フィールドを使用しません。
  • force_shredded_fields: シャード化されたフィールドをスキャンしてもテーブル スキャンを実行できない場合は、クエリを失敗させます。

var opts = new PipelineExecuteOptions()
    .with("table_scan_method", "shredded_fields_disabled");

var snapshot = db.pipeline()
    .collection("/customers")
    .where(equal("given_name", "alice"))
    .execute(opts)
    .get();

クエリのパフォーマンスに関する警告

非効率的なシュレッド フィールドの使用が検出されると、Cloud Firestore はクエリの説明結果でパフォーマンス警告を発行することがあります。例:

  • 選択性の低いクエリ: クエリがフィルタリングのためにシュレッドされたフィールドをスキャンするが、フィルタリングされるドキュメントが少なすぎてスキャンが非効率的になる場合に発生します。

  • 再チェック頻度の高いクエリ: クエリが頻繁にドキュメントの完全読み取りにフォールバックする場合に発生します。パフォーマンスに影響する可能性があります。storage_size などの関数を使用して、再チェックをトリガーする大きな値を特定できます。

このような場合は、クエリ オプションを使用して、シュレッド フィールドの読み取りを無効にすることを検討してください。

制限事項

Cloud Firestore は最上位のフィールドのみをシュレッドします。また、コレクション グループごとにシュレッドできるフィールドの数も制限します。