クラスタ化テーブルのクエリ

クラスタ化テーブルのクエリ

BigQuery でクラスタ化テーブルを作成すると、テーブルのスキーマ内の 1 つ以上の列の内容に基づいてテーブルのデータが自動的に編成されます。指定した列は、関連するデータを同じ場所に配置するために使用されます。複数の列を使用してテーブルをクラスタ化する場合は、指定する列の順序が重要です。指定した列の順序によって、データの並べ替え順序が決まります。

クラスタ化テーブルに対してクエリを実行するときのパフォーマンスを最適化するには、クラスタ化列を指定した際の順序で、1 つまたは複数のクラスタ化列をフィルタリングする式を使用します。通常、クラスタ化列でフィルタリングするクエリは、非クラスタ化列のみでフィルタリングするクエリよりも優れたパフォーマンスを発揮します。

BigQuery は、クラスタリング列の値に基づいてクラスタ化テーブルのデータを並べ替えて、データをブロックに整理します。

クラスタ化列のフィルタを含むクエリを送信すると、BigQuery はクラスタリング情報を使用して、クエリに関連するデータがブロックに含まれているかどうかを効率的に判断します。これにより、BigQuery は関連するブロックのみをスキャンできます。このプロセスはブロック プルーニングと呼ばれます。

次の方法で、クラスタ化テーブルにクエリを実行できます。

  • GCP Console または従来の BigQuery ウェブ UI を使用する
  • コマンドライン ツールの bq query コマンドを使用する
  • jobs.insert API メソッドを呼び出してクエリジョブを構成する

現時点では、クラスタ化テーブルでは標準 SQL のみを使用できます。

必要な権限

データセット レベルでクラスタ化テーブルにクエリを行うには、テーブルが含まれるデータセットへの READER アクセス権が必要です。

データセット レベルの権限を使用する代わりに、bigquery.tables.getData 権限が含まれるプロジェクト レベルの IAM 役割を利用できます。 クエリの対象となるテーブルのデータを読み取るには、bigquery.tables.getData 権限が必要です。事前定義されているプロジェクト レベルの IAM 役割のうち、bigquery.userbigquery.jobUserbigquery.metadataViewer 以外の役割にはすべて bigquery.tables.getData 権限が含まれています。

クエリジョブを実行するには、bigquery.jobs.create 権限が付与されていることも必要です。次の定義済みのプロジェクト レベルの IAM 役割には bigquery.jobs.create 権限が含まれています。

BigQuery での IAM 役割と権限の詳細については、アクセス制御をご覧ください。データセット レベルの役割の詳細については、データセットに対する基本の役割をご覧ください。

ベスト プラクティス

クラスタ化テーブルに対するクエリから最高のパフォーマンスを得るには、次のベスト プラクティスを使用します。

以下の例で使用されているサンプル テーブル

このページの例で使用されているサンプル テーブルは、DDL ステートメントを使用して作成されたクラスタ化テーブルです。この DDL ステートメントは、ClusteredSalesData という名前のテーブルを作成します。このテーブルは、customer_id 列、product_id 列、order_id 列の順でクラスタ化されています。

CREATE TABLE
  `mydataset.ClusteredSalesData`
PARTITION BY
  DATE(timestamp)
CLUSTER BY
  customer_id,
  product_id,
  order_id AS
SELECT
  *
FROM
  `mydataset.SalesData`

並べ替え順序でクラスタ化列をフィルタリングする

フィルタを指定するときは、並べ替え順序でクラスタ化列をフィルタリングする式を使用します。

次のクエリには、customer_id でフィルタリングし、次に product_id でフィルタリングするフィルタ式が含まれています。このクエリでは、並べ替え順序でクラスタ化列をフィルタリングしているため、パフォーマンスが最適化されます。

SELECT
  SUM(totalSale)
FROM
  `mydataset.ClusteredSalesData`
WHERE
  customer_id = 10000
  AND product_id LIKE 'gcp_analytics%'

次のクエリは、フィルタリングにおいてクラスタ化列が並べ替え順序になっていません。その結果、このクエリのパフォーマンスは最適化されません。このクエリでは、最初に product_id でフィルタリングされ、次に order_id でフィルタリングされます(customer_id はスキップしています)。

SELECT
  SUM(totalSale)
FROM
  `mydataset.ClusteredSalesData`
WHERE
  product_id LIKE 'gcp_analytics%'
  AND order_id = 20000

複雑なフィルタ式ではクラスタ化列を使用しない

複雑なフィルタ式でクラスタ化列を使用すると、ブロック プルーニングを適用できないため、クエリのパフォーマンスが最適化されません。

たとえば、次のクエリは、クラスタ化列(customer_id)がフィルタ式の関数の中で使用されているため、ブロック プルーニングが行われません。

SELECT
  SUM(totalSale)
FROM
  `mydataset.ClusteredSalesData`
WHERE
  CAST(customer_id AS STRING) = "10000"

ブロック プルーニングによってクエリのパフォーマンスを最適化するには、次のような単純なフィルタ式を使用します。この例では、単純なフィルタがクラスタ化列(customer_id)に適用されます。

SELECT
  SUM(totalSale)
FROM
  `mydataset.ClusteredSalesData`
WHERE
  customer_id = 10000

クラスタ化列を他の列と比較しない

フィルタ式でクラスタ化列を他の列(クラスタ化列、非クラスタ化列のいずれでも)と比較する場合、ブロック プルーニングを適用できないため、クエリのパフォーマンスは最適化されません。

次のクエリでは、フィルタ式でクラスタ化列(customer_id)と他の列(order_id)を比較しているため、ブロック プルーニングが行われません。

SELECT
  SUM(totalSale)
FROM
  `mydataset.ClusteredSalesData`
WHERE
  customer_id = order_id

次のステップ

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

ご不明な点がありましたら、Google のサポートページをご覧ください。