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

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

概要

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

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

制限事項

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

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

料金と割り当て

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

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

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

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

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

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

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

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

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

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

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

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

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

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

従来の UI

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

  2. [COMPOSE QUERY] ボタンをクリックします。

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

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

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

コマンドライン

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

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

API

キャッシュに保存されている結果を使用せずにクエリを処理するには、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 のリファレンス ドキュメントをご覧ください。

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

// Creates 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,
};

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

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

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

Java

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

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

// 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() 関数を使用してクエリを実行する場合、ジョブ構成の createDisposition プロパティを CREATE_NEVER に設定することで、キャッシュに保存されている結果を使用できない場合に限り、クエリジョブを強制的に失敗させることができます。

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

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

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

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

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

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

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

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

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