シュレッド フィールドで最適化されたクエリ

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

ドキュメントが書き込まれると、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)
    
  • フィルタ クエリ: 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]

シュレッド フィールドの使用状況を制御する

デフォルトでは、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();

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

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

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

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

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

制限事項

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