キャッシュに保存されているクエリ結果を使用する

このドキュメントでは、BigQuery のキャッシュに保存されているクエリ結果を使用する方法について説明します。

概要

BigQuery はすべてのクエリ結果をテーブルに書き込みます。テーブルはユーザーが明示的に指定されたテーブルか(宛先テーブル)、一時的なキャッシュ結果テーブルのいずれかです。一時的なキャッシュ結果テーブルは、ユーザー別、プロジェクト別に保持されます。一時的なテーブルにはストレージの費用がかかりませんが、永続的なテーブルにクエリ結果を書き込むと、そのデータの保存に対して課金されます。

インタラクティブ クエリとバッチクエリの両方を含むすべてのクエリの結果は、一部の例外を除いて、一時テーブルに約 24 時間キャッシュされます。

制限事項

クエリ キャッシュの使用には以下の制限があります。

  • 同じクエリを重複して実行すると、BigQuery はキャッシュに保存された結果を再利用しようとします。キャッシュからデータを取得するには、複製されたクエリテキストを元のクエリと完全に同じにする必要があります。
  • クエリ結果がキャッシュ結果テーブルに存続するためには、結果セットを最大レスポンス サイズよりも小さくする必要があります。サイズの大きな結果セットの管理について詳しくは、大きいクエリ結果を返すをご覧ください。
  • キャッシュ結果テーブルは DML ステートメントのターゲットにできません。
  • 現在のセマンティクスでは可能ですが、キャッシュに保存された結果を従属ジョブの入力として使用することは推奨されません。たとえば、キャッシュ テーブルから結果を取得するクエリジョブを送信しないでください。その代わりに、結果を名前付き宛先テーブルに書き込んでください。簡単にクリーンアップできるよう、データセット レベルの defaultTableExpirationMs プロパティなどの機能でデータを一定期間後に自動的に期限切れにできます。

料金と割り当て

クエリ結果がキャッシュ結果テーブルから取得された場合、ジョブ統計プロパティ statistics.query.cacheHittrue として返され、そのクエリについては課金されません。キャッシュに保存された結果を使用したクエリは、課金の対象となりませんが、BigQuery の割り当てポリシーの対象にはなります。キャッシュに保存された結果を使用したクエリには、コスト削減に加えて、非常に高速であるという利点もあります。これは BigQuery が結果セットを計算する必要がないためです。

クエリのキャッシュの例外

次の場合、クエリ結果はキャッシュに保存されません。

  • 宛先テーブルがジョブ構成、GCP Console、従来のウェブ UI、コマンドライン、または API で指定されている場合
  • 結果がキャッシュに保存された後に、参照先のテーブルまたは論理ビューが変更された場合
  • クエリによって参照されているいずれかのテーブルが最近ストリーミング挿入を受信していたとき(ストリーミング バッファがテーブルに添付されている)。そのテーブルが新しい行を受け取ったかどうかは問いません
  • CURRENT_TIMESTAMP()NOW() といった日時関数や CURRENT_USER() 関数など、実行タイミングによって異なる値を返す非決定性関数がクエリで使用されている場合
  • ワイルドカードを使用して複数のテーブルに対してクエリを実行する場合
  • キャッシュに保存された結果が期限切れとなった場合。通常、キャッシュのライフタイムは 24 時間ですが、キャッシュへの保存はベスト エフォート式であり、すぐに無効になることがあります
  • クエリが外部データソースに対して実行されている場合

キャッシュされた結果の保存方法

クエリを実行すると、一時的なキャッシュ結果テーブルは「匿名データセット」と呼ばれる特別なデータセットに作成されます。匿名データセットに対するアクセス権は、IAM リソース階層モデル(プロジェクトと組織の権限)から権限を継承する通常のデータセットとは異なり、データセット所有者に限られます。匿名データセットの所有者は、キャッシュされた結果を生成したクエリを実行したユーザーです。

匿名データセットが作成されると、クエリジョブを実行するユーザーには、匿名データセットに対する bigquery.dataOwner アクセス権が明示的に付与されます。bigquery.dataOwner アクセス権は、クエリジョブを実行したユーザーだけにデータセット全体を制御する権限を与えます。この権限には、匿名データセットのキャッシュ結果テーブル全体を制御する権限が含まれます。クエリ結果を共有する場合は、匿名データセットに格納されたキャッシュ結果を使用しないでください。その代わりに、結果を名前付き宛先テーブルに書き込んでください。

クエリを実行するユーザーは、データセットとキャッシュ結果テーブルへの完全アクセス権を持っていますが、従属ジョブの入力としてそれらを使用することは推奨されません。

匿名データセットの名前の先頭はアンダースコアです。これにより、GCP Console と従来の BigQuery ウェブ UI のデータセットのリストが非表示になります。CLI または API を使用して、匿名データセットを一覧表示し、匿名データセットのアクセス制御を監査できます。

キャッシュに保存されている結果の取得を無効にする

[Use cached results] オプションでは、クエリ対象のテーブルが変更された場合を除いて、以前に実行された同じクエリの結果が再利用されます。キャッシュされた結果の使用が役立つのは、クエリを繰り返し実行する場合のみです。新規のクエリでは [Use cached results] オプションの効果がありませんが、デフォルトで有効になっています。

[Use cached results] オプションを無効にしてクエリを繰り返し実行すると、既存のキャッシュされた結果が上書きされます。この場合、BigQuery でクエリ結果を計算する必要があり、そのクエリに対して課金が発生します。これは、ベンチマークに非常に役立ちます。

キャッシュされた結果の取得を無効にしてクエリジョブの実行評価を強制的に行う場合は、クエリジョブの configuration.query.useQueryCache プロパティを false に設定します。

[Use cached results] オプションを無効にするには:

Console

  1. GCP Console を開きます。
    GCP Console に移動する

  2. [クエリを新規作成] をクリックします。

  3. [クエリエディタ] テキスト領域に有効な SQL クエリを入力します。

  4. [展開] をクリックして、[クエリの設定] を選択します。

    クエリの設定

  5. [キャッシュの設定] の [キャッシュに保存された結果を使用] をオフにします。

    キャッシュに保存された結果オプション

従来の UI

  1. 従来の BigQuery ウェブ UI に移動します。
    BigQuery ウェブ UI に移動

  2. [クエリを作成] ボタンをクリックします。

  3. [New Query] テキスト領域に有効な SQL クエリを入力します。

  4. [Show Options] をクリックします。

  5. [Use Cached Results] をオフにします。

キャッシュに保存された結果オプション

CLI

クエリ キャッシュを上書きするには、nouse_cache フラグを指定します。次の例では、BigQuery が既存のキャッシュされた結果を使用することなく、クエリを強制的に処理します。

 bq query \
 --nouse_cache \
 --batch \
 'SELECT
    name,
    count
  FROM
    `my-project`.mydataset.names_2013
  WHERE
    gender = "M"
  ORDER BY
    count DESC
  LIMIT
    6'

API

キャッシュに保存されている結果を使用せずにクエリを処理するには、query ジョブ構成で useQueryCache プロパティを false に設定します。

Go

このサンプルを試す前に、BigQuery クイックスタート: クライアント ライブラリの使用の Go の設定手順を実施してください。詳細については、BigQuery Go API のリファレンス ドキュメントをご覧ください。

// To run this sample, you will need to create (or reuse) a context and
// an instance of the bigquery client.  For example:
// import "cloud.google.com/go/bigquery"
// ctx := context.Background()
// client, err := bigquery.NewClient(ctx, "your-project-id")

q := client.Query(
	"SELECT corpus FROM `bigquery-public-data.samples.shakespeare` GROUP BY corpus;")
q.DisableQueryCache = true
// Location must match that of the dataset(s) referenced in the query.
q.Location = "US"
job, err := q.Run(ctx)
if err != nil {
	return err
}
status, err := job.Wait(ctx)
if err != nil {
	return err
}
if err := status.Err(); err != nil {
	return err
}
it, err := job.Read(ctx)
for {
	var row []bigquery.Value
	err := it.Next(&row)
	if err == iterator.Done {
		break
	}
	if err != nil {
		return err
	}
	fmt.Println(row)
}

Node.js

このサンプルを試す前に、BigQuery クイックスタート: クライアント ライブラリの使用の Node.js の設定手順に従ってください。詳細については、BigQuery Node.js API のリファレンス ドキュメントをご覧ください。

// Import the Google Cloud client library
const {BigQuery} = require('@google-cloud/bigquery');

async function queryDisableCache() {
  // Queries the Shakespeare dataset with the cache disabled.

  // Create a client
  const bigquery = new BigQuery();

  const query = `SELECT corpus
    FROM \`bigquery-public-data.samples.shakespeare\`
    GROUP BY corpus`;
  const options = {
    query: query,
    // Location must match that of the dataset(s) referenced in the query.
    location: 'US',
    useQueryCache: false,
  };

  // Run the query as a job
  const [job] = await bigquery.createQueryJob(options);
  console.log(`Job ${job.id} started.`);

  // Wait for the query to finish
  const [rows] = await job.getQueryResults();

  // Print the results
  console.log('Rows:');
  rows.forEach(row => console.log(row));
}

Java

キャッシュに保存されている結果を使用せずにクエリを処理するには、QueryJobConfiguration の作成時に setUseQueryCachefalse に設定します。

// BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();
String query = "SELECT corpus FROM `bigquery-public-data.samples.shakespeare` GROUP BY corpus;";
QueryJobConfiguration queryConfig =
    QueryJobConfiguration.newBuilder(query)
        // Disable the query cache to force live query evaluation.
        .setUseQueryCache(false)
        .build();

// Print the results.
for (FieldValueList row : bigquery.query(queryConfig).iterateAll()) {
  for (FieldValue val : row) {
    System.out.printf("%s,", val.toString());
  }
  System.out.printf("\n");
}

Python

このサンプルを試す前に、BigQuery クイックスタート: クライアント ライブラリの使用の Python の設定手順を実施してください。詳細については、BigQuery Python API のリファレンス ドキュメントをご覧ください。

# from google.cloud import bigquery
# client = bigquery.Client()

job_config = bigquery.QueryJobConfig()
job_config.use_query_cache = False
sql = """
    SELECT corpus
    FROM `bigquery-public-data.samples.shakespeare`
    GROUP BY corpus;
"""
query_job = client.query(
    sql,
    # Location must match that of the dataset(s) referenced in the query.
    location="US",
    job_config=job_config,
)  # API request

# Print the results.
for row in query_job:  # API request - fetches results
    print(row)

キャッシュを確実に使用する

jobs.insert 関数を使用してクエリを実行する場合、copy ジョブ構成の createDisposition プロパティを CREATE_NEVER に設定することで、キャッシュに保存されている結果を使用できないときはクエリジョブを強制的に失敗させることができます。

クエリ結果がキャッシュに存在しない場合は、NOT_FOUND エラーが返されます。

キャッシュの使用を検証する

BigQuery がキャッシュを使用して結果を返したかどうかを判定する方法は 2 つあります。

  • GCP Console や従来の BigQuery ウェブ UI を使用している場合は、結果の文字列に処理バイト数に関する情報が含まれず、「キャッシュ済み」という単語が表示されます。

    UI のキャッシュ インジケーター

  • BigQuery API を使用している場合は、クエリ結果の cacheHit プロパティが true に設定されます。

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

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

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