BigQuery で費用を抑える

このページでは、BigQuery で費用を抑えるためのおすすめの方法について説明します。

SELECT * を避ける

おすすめの方法: 必要な列のみを照会します。

SELECT * の使用は、データを照会するのに最も費用がかかる方法です。SELECT * を使用すると、BigQuery はテーブル内のすべての列をフルスキャンします。

データのテストまたは探索には、SELECT * ではなく、いずれかのデータ プレビュー オプションを使用してください。

LIMIT 句を SELECT * クエリに適用しても、読み取られるデータの量には影響しません。テーブル全体のすべてのバイトの読み取りに対して課金され、クエリは無料枠割り当ての対象としてカウントされます。

代わりに、必要な列のみを照会します。たとえば、SELECT * EXCEPT を使用して、結果から 1 つ以上の列を除外します。

テーブル内のすべての列を対象とするものの、データのサブセットに対してのみクエリを実行する必要がある場合は、以下のことを検討してください。

  • 代わりに、宛先テーブルで結果を実体化し、そのテーブルを照会する。
  • テーブルを日付別にパーティショニングし、関連するパーティションに対してクエリを実行する。たとえば、WHERE _PARTITIONDATE="2017-01-01" と指定すると、2017 年 1 月 1 日のパーティションのみがスキャンされます。

プレビュー オプションを使用してデータをサンプリングする

おすすめの方法: テーブルデータを探索またはプレビューするためにクエリを実行しないでください。

データを試したり調べたりする場合は、テーブル プレビュー オプションを使用すれば、割り当てに影響を与えることなく、無料でデータを表示できます。

BigQuery は、次のデータ プレビュー オプションをサポートしています。

  • Cloud Console または従来のウェブ UI のテーブルの詳細ページで、[プレビュー] タブをクリックしてデータをサンプリングする。
  • bq コマンドライン ツールで、bq head コマンドを使用して、プレビューする行数を指定します。
  • API で tabledata.list を使用して、指定した行のセットからテーブルデータを取得する。

クエリを実行する前に料金を見積もる

おすすめの方法: クエリを実行する前に、プレビューして費用を見積もります。

クエリは、読み取られたバイト数に基づいて課金されます。クエリを実行する前に費用を見積もるには、以下を行います。

  • Cloud Console または従来のウェブ UI でクエリ検証ツールを表示する
  • Google Cloud Platform 料金計算ツールを使用する
  • 以下を使用して、ドライランを実行する
    • bq コマンドライン ツールの --dry_run フラグ
    • dryRun パラメータ(API を使用してクエリジョブを送信する場合)

クエリ検証ツールの使用

Cloud Console または従来のウェブ UI でクエリを入力すると、クエリ検証ツールがクエリ構文を検証し、読み取りバイト数を見積もります。この見積もりを料金計算ツールで使用すると、クエリ費用を計算できます。

クエリ検証ツール

ドライランの実行

ドライランを実行するには、次の手順に従います。

Console

現時点では、Cloud Console を使用してドライランを実行することはできません。

従来の UI

現時点では、ウェブ UI を使用してドライランを実行することはできません。

bq

--dry_run フラグを使用して次のようなクエリを入力します。

bq query \
--use_legacy_sql=false \
--dry_run \
'SELECT
   COUNTRY,
   AIRPORT,
   IATA
 FROM
   `project_id`.dataset.airports
 LIMIT
   1000'
 

このコマンドにより、次のレスポンスが生成されます。

Query successfully validated. Assuming the tables are not modified,
running this query will process 10918 bytes of data.

API

API を使用してドライランを実行するには、JobConfiguration タイプで dryRuntrue に設定してクエリジョブを送信します。

Go

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

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/bigquery"
)

// queryDryRun demonstrates issuing a dry run query to validate query structure and
// provide an estimate of the bytes scanned.
func queryDryRun(w io.Writer, projectID string) error {
	// projectID := "my-project-id"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	q := client.Query(`
	SELECT
		name,
		COUNT(*) as name_count
	FROM ` + "`bigquery-public-data.usa_names.usa_1910_2013`" + `
	WHERE state = 'WA'
	GROUP BY name`)
	q.DryRun = 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
	}
	// Dry run is not asynchronous, so get the latest status and statistics.
	status := job.LastStatus()
	if err != nil {
		return err
	}
	fmt.Fprintf(w, "This query will process %d bytes\n", status.Statistics.TotalBytesProcessed)
	return nil
}

Java

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

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.JobStatistics;
import com.google.cloud.bigquery.QueryJobConfiguration;

// Sample to run dry query on the table
public class QueryDryRun {

  public static void runQueryDryRun() {
    String query =
        "SELECT name, COUNT(*) as name_count "
            + "FROM `bigquery-public-data.usa_names.usa_1910_2013` "
            + "WHERE state = 'WA' "
            + "GROUP BY name";
    queryDryRun(query);
  }

  public static void queryDryRun(String query) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      QueryJobConfiguration queryConfig =
          QueryJobConfiguration.newBuilder(query).setDryRun(true).setUseQueryCache(false).build();

      Job job = bigquery.create(JobInfo.of(queryConfig));
      JobStatistics.QueryStatistics statistics = job.getStatistics();

      System.out.println(
          "Query dry run performed successfully." + statistics.getTotalBytesProcessed());
    } catch (BigQueryException e) {
      System.out.println("Query not performed \n" + e.toString());
    }
  }
}

Python

Python クライアント ライブラリを使用してドライランを実行するには、QueryJobConfig.dry_run プロパティを True に設定します。ドライランのクエリ構成が渡されると、Client.query() は常に完了した QueryJob を返します。

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

from google.cloud import bigquery

# Construct a BigQuery client object.
client = bigquery.Client()

job_config = bigquery.QueryJobConfig(dry_run=True, use_query_cache=False)

# Start the query, passing in the extra configuration.
query_job = client.query(
    (
        "SELECT name, COUNT(*) as name_count "
        "FROM `bigquery-public-data.usa_names.usa_1910_2013` "
        "WHERE state = 'WA' "
        "GROUP BY name"
    ),
    job_config=job_config,
)  # Make an API request.

# A dry run query completes immediately.
print("This query will process {} bytes.".format(query_job.total_bytes_processed))

料金計算ツールの使用

Google Cloud Platform 料金計算ツールでクエリ費用を見積もるには、クエリで処理されるバイト数を MB、GB、TB、または PB として入力します。クエリで 1 TB 未満が処理される場合は、BigQuery が 1 TB のオンデマンド クエリ処理を 1 か月間無料で提供するため、見積もりは $0 になります。

料金計算ツール

課金されるバイト数を制限してクエリ費用を抑える

おすすめの方法: 課金される最大バイト数の設定を使用して、クエリ費用を抑えます。

課金されるクエリのバイト数を制限するには、課金される最大バイト数の設定を使用します。課金される最大バイト数を設定した場合は、クエリが制限を超えたバイト数を読み取ると、課金されずにクエリが失敗します。

課金される最大バイト数を設定したことによってクエリが失敗した場合は、次のようなエラーが返されます。

Error: Query exceeded limit for bytes billed: 1000000. 10485760 or higher required.

課金される最大バイト数を設定するには:

Console

  1. クエリエディタで、[展開] をクリックし、[クエリの設定] をクリックしてから、[詳細オプション] をクリックします。
  2. [課金される最大バイト数] フィールドに整数を入力します。
  3. [保存] をクリックします。

bq

bq query コマンドを使用し、--maximum_bytes_billed フラグを指定します。

  bq query --maximum_bytes_billed=1000000 \
  --use_legacy_sql=false \
  'SELECT
     word
   FROM
     `bigquery-public-data`.samples.shakespeare'

API

JobConfigurationQuery または QueryRequestmaximumBytesBilled プロパティを設定します。

LIMIT は費用に影響しない

おすすめの方法: LIMIT 句をコスト管理の手法として使用しないでください。

LIMIT 句をクエリに適用しても、読み取られるデータの量は変わりません。結果セットの出力が制限されるだけです。クエリによって指定されたテーブル全体のすべてのバイトの読み取りに対して課金されます。

LIMIT 句の有無に関係なく、クエリによって読み取られるデータの量は、無料枠割り当ての対象としてカウントされます。

ダッシュボードを使用して費用を表示し、監査ログを照会する

おすすめの方法: BigQuery の使用量を調整できるように、課金データを表示するためのダッシュボードを作成します。また、使用パターンを分析できるように、BigQuery への監査ログのストリーミングも検討します。

BigQuery に課金データをエクスポートすると、Google データポータルなどのツールで可視化できます。課金ダッシュボードの作成方法のチュートリアルについては、BigQuery と Google データポータルを使用した GCP 課金の可視化をご覧ください。

また、監査ログを BigQuery にストリーミングして、ユーザー別のクエリ費用などの使用パターンに関するログを分析することもできます。

データを日付別にパーティション分割する

おすすめの方法: テーブルを日付別にパーティショニングします。

可能であれば、BigQuery テーブルを日付別にパーティショニングします。テーブルをパーティショニングすることで、関連するデータのサブセットをクエリして、パフォーマンスを向上させ、コストを削減できます。

たとえば、パーティション分割テーブルを照会するときに、_PARTITIONTIME 擬似列を使用して日付または日付の範囲をフィルタ処理します。クエリは、日付または範囲で指定されたパーティション内のデータのみを処理します。

クエリ結果を段階的に実体化する

おすすめの方法: 可能であれば、クエリ結果を段階的に実体化します。

大容量のマルチステージ クエリを作成すると、それを実行するたびに、BigQuery がそのクエリに必要なすべてのデータを読み取ります。クエリが実行されるたびに読み取られるすべてのデータに対して課金されます。

代わりに、クエリを複数のステージに分割し、各ステージでクエリ結果を宛先テーブルに書き込むことにより実体化します。小容量の宛先テーブルを照会することにより、読み取られるデータの量が削減され、費用が削減されます。実体化された結果を保存する費用は、大量のデータを処理する費用よりはるかに少なくなります。

大容量の結果セットの費用を検討する

おすすめの方法: 大容量のクエリ結果を宛先テーブルに書き込む場合は、デフォルトのテーブル有効期限を適用して不要になったデータを削除します。

BigQuery ストレージで大容量の結果セットを維持するには費用がかかります。結果に永続的にアクセスする必要がなければ、デフォルトのテーブル有効期限を使用して自動的にデータを削除するようにします。

詳細については、ストレージの料金をご覧ください。

ストリーミング挿入は慎重に使用する

おすすめの方法: ストリーミング挿入は、データをすぐに公開する必要がある場合にのみ使用します。

BigQuery へのデータの読み込みは無料です。一方、BigQuery へのデータのストリーミングに対しては料金が発生します。データを即時利用可能にする必要がある場合を除き、データはストリーミングするのではなく、読み込んでください。