テーブルのサンプリング

テーブルのサンプリングを使用すると、大規模な BigQuery テーブルからランダムなサブセットのデータに対してクエリを実行できます。サンプリングは、テーブル全体のスキャンと処理に関連する費用を回避しながら、さまざまなレコードを返します。

テーブルのサンプリングの使用

クエリでテーブル サンプリングを使用するには、TABLESAMPLE 句を含めます。たとえば、次のクエリはテーブルデータの約 10% を選択します。

SELECT * FROM dataset.my_table TABLESAMPLE SYSTEM (10 PERCENT)

LIMIT 句とは異なり、TABLESAMPLE はテーブルからランダムなサブセットのデータを返します。また、BigQuery は TABLESAMPLE 句を含むクエリの結果をキャッシュに保存しないため、毎回異なる結果が返される可能性があります。

TABLESAMPLE 句は他の選択条件と組み合わせることができます。次の例では、テーブルの約 50% をサンプリングし、WHERE 句を適用します。

SELECT *
FROM dataset.my_table TABLESAMPLE SYSTEM (50 PERCENT)
WHERE customer_id = 1

次の例では、TABLESAMPLE 句と JOIN 句を組み合わせます。

SELECT *
FROM dataset.table1 T1 TABLESAMPLE SYSTEM (10 PERCENT)
JOIN dataset.table2 T2 TABLESAMPLE SYSTEM (20 PERCENT) USING (customer_id)

小さいテーブルの場合、2 つのサンプルを結合すると、サンプリングした行で結合条件が満たされていない場合に空の結果が返されることがあります。

割合をクエリ パラメータとして指定できます。次の例は、bq コマンドライン ツールを使用して割合をクエリに渡す方法を示しています。

bq query --use_legacy_sql=false --parameter=percent:INT64:29 \
    'SELECT * FROM `dataset.my_table` TABLESAMPLE SYSTEM (@percent PERCENT)`

BigQuery テーブルは、データブロックに編成されています。TABLESAMPLE 句は、テーブルから特定のデータブロックの割合をランダムに選択し、選択したブロック内のすべての行を読み取ります。サンプリングの粒度はデータブロックの数によって制限されます。

通常、BigQuery は、テーブルまたはテーブル パーティションが約 1 GB より大きい場合、ブロックに分割します。小さいテーブルは、1 つのデータブロックで構成されている場合があります。その場合、TABLESAMPLE 句はテーブル全体を読み取ります。サンプリングの割合がゼロより大きく、テーブルが空でない場合、テーブル サンプリングで常に結果が返されます。

ブロックのサイズは異なるため、サンプリングされる行の正確な数は異なる場合があります。データブロックではなく個々の行をサンプリングする場合は、代わりに WHERE rand() < K 句を使用します。ただし、この方法ではテーブル全体をスキャンする必要があります。費用を抑えながら行レベルのサンプリングを行うには、両方の手法を組み合わせることができます。

次の例では、データブロックの約 20% をストレージから読み取り、それらのブロックで行の 10% をランダムに選択します。

SELECT * FROM dataset.my_table TABLESAMPLE SYSTEM (20 PERCENT)
WHERE rand() < 0.1

外部テーブル

TABLESAMPLE 句は、ファイルのコレクションにデータを保存する外部テーブルで使用できます。BigQuery では、テーブルが参照する外部ファイルのサブセットをサンプリングします。一部のファイル形式では、BigQuery で個々のファイルをサンプリング用にブロックに分割できます。一部の外部データ(Google スプレッドシートのデータなど)は、1 つのデータブロックとしてサンプリングされる単一ファイルで構成されています。

書き込み用に最適化されたストレージからのサンプリング

ストリーミング挿入でテーブル サンプリングを使用する場合、BigQuery は書き込み用に最適化されたストレージからデータをサンプリングします。場合によっては、書き込み用に最適化されたストレージ内のすべてのデータが 1 つのブロックとして表されることがあります。その場合、書き込み用に最適化されたストレージのすべてのデータが結果に表示されるか、まったく表示されないかのいずれかになります。

パーティション分割テーブルとクラスタ化テーブル

パーティショニングとクラスタリングにより、特定のブロック内のすべての行が同じパーティショニング キーのあるブロック、または近い値を使用したクラスタリング属性があるブロックが生成されます。したがって、これらのテーブルからのサンプルセットは、パーティション分割もクラスタ化もされていないテーブルのサンプルセットよりもバイアスが含まれやすい傾向にあります。

制限事項

  • サンプリングされたテーブルは、クエリ ステートメント内で 1 回のみ使用できます。この制限には、ビュー定義内で参照されるテーブルも含まれます。
  • ビューからのサンプリング データはサポートされていません。
  • サブクエリやテーブル値の関数呼び出しの結果をサンプリングすることはできません。
  • UNNEST 演算子の呼び出しの結果など、配列スキャンからのサンプリングはサポートされていません。
  • IN サブクエリ内のサンプリングはサポートされていません。
  • 行レベルのセキュリティが適用されたテーブルからのサンプリングは、サポートされていません。

テーブルのサンプリングの料金

オンデマンド課金を使用する場合、サンプリングされたデータの読み取りに対して料金が発生します。BigQuery は、TABLESAMPLE 句を含むクエリの結果をキャッシュに保存しないため、実行のたびにストレージからデータを読み取り、書き込みを行います。