ストレージとクエリの費用の見積もり

BigQuery では、オンデマンド クエリは読み取られたバイト数に基づいて課金されます。現在のオンデマンド クエリの料金については、料金ページをご覧ください。

クエリを実行する前に費用を見積もるには、次のいずれかの方法を使用します。

  • Cloud Console のクエリ検証ツール
  • bq コマンドライン ツールの --dry_run フラグ
  • dryRun パラメータ(API を使用してクエリジョブを送信する場合)
  • Google Cloud 料金計算ツール
  • クライアント ライブラリ

この方法で提供される費用は概算で、いくつかの要因により、実際の費用とは異なる場合があります。たとえば、次のようなシナリオについて考えてみましょう。

  • WHERE 句など、データをフィルタするクエリ句により、読み取られるバイト数が大幅に減少する可能性があります。
  • 見積もり後に追加または削除されるデータにより、クエリ実行時に読み取られるバイト数が増加または減少する可能性があります。

クエリの費用を見積もる

クエリ費用を見積もるには:

Console

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

クエリ検証ツール

bq

bq コマンドライン ツールでクエリを実行するときは、--dry_run フラグを使用して、読み取られるバイト数を見積もることができます。この見積もりを使用して料金計算ツールで、クエリ費用を計算できます。

--dry_run フラグを使用する bq ツールクエリは、次のようになります。

bq query \
--use_legacy_sql=false \
--dry_run \
'SELECT
  column1,
  column2,
  column3
FROM
  `project_id.dataset.table`
LIMIT
  1000'

このコマンドを実行すると、レスポンスに次のように推定読み取りバイト数が示されます。Query successfully validated. Assuming the tables are not modified, running this query will process 10918 bytes of data.

API

API を使用してドライランを実行するには、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());
    }
  }
}

Node.js

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

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

async function queryDryRun() {
  // Runs a dry query of the U.S. given names dataset for the state of Texas.

  const query = `SELECT name
    FROM \`bigquery-public-data.usa_names.usa_1910_2013\`
    WHERE state = 'TX'
    LIMIT 100`;

  // For all options, see https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/query
  const options = {
    query: query,
    // Location must match that of the dataset(s) referenced in the query.
    location: 'US',
    dryRun: true,
  };

  // Run the query as a job
  const [job] = await bigquery.createQueryJob(options);

  // Print the status and statistics
  console.log('Status:');
  console.log(job.metadata.status);
  console.log('\nJob Statistics:');
  console.log(job.metadata.statistics);
}

Python

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

Python クライアント ライブラリを使用してドライランを実行するには、QueryJobConfig.dry_run プロパティを True に設定します。ドライランのクエリ構成が渡されると、Client.query() は常に完了した QueryJob を返します。
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 料金計算ツールを使用してクエリの費用を見積もる

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

料金計算ツール

料金計算ツールを使用してクエリ費用を見積もるには:

  1. Google Cloud 料金計算ツールを開きます。
  2. [BigQuery] をクリックします。
  3. [ON-DEMAND] タブをクリックします。
  4. [Table Name] に、テーブルの名前を入力します。例: airports
  5. [Storage Pricing] の [Storage] フィールドに「0」と入力します。
  6. [Query Pricing] に、ドライランまたはクエリ検証ツールから返された推定読み取りバイト数を入力します。 計算ツール
  7. [Add To Estimate] をクリックします。
  8. 見積もりが右側に表示されます。見積もりの保存やメールの送信を行うことができます。オンデマンド計算ツール

この場合、クエリで読み取られるバイト数は、無料枠で提供されるオンデマンド処理の 1 TB 未満です。そのため、見積もり用は $0 です。

料金計算ツールに定額料金を含める

請求先アカウントに定額料金が適用されている場合は、[FLAT-RATE] タブをクリックして定額料金プランを選択し、見積もりにストレージ費用を追加できます。

定額計算ツール

詳細については、定額料金をご覧ください。

Google Cloud 料金計算ツールを使用してストレージ費用を見積もる

Google Cloud 料金計算ツールでストレージ費用を見積もるには、保存されるバイト数を B、KB、MB、GB、TB、および PB 単位で入力します。BigQuery では月間 10 GB のストレージが無料で提供されます。

料金計算ツールを使用してストレージ費用を見積もるには:

  1. Google Cloud 料金計算ツールを開きます。
  2. [BigQuery] をクリックします。
  3. [ON-DEMAND] タブをクリックします。
  4. [Table Name] に、テーブルの名前を入力します。例: airports
  5. [Storage Pricing] の [Storage] フィールドに「100」と入力します。測定単位を GB に設定したままにします。
  6. [Add To Estimate] をクリックします。
  7. 見積もりが右側に表示されます。見積もりの保存やメールの送信を行うことができます。料金計算ツール

クエリサイズの計算

このセクションでは、オンデマンド課金モデルを使用して、さまざまなタイプのクエリで処理されるバイト数を計算する方法について説明します。

DML ステートメント

オンデマンド課金の場合、BigQuery がデータ操作言語(DML)ステートメントで処理したバイト数に基づいて課金されます。

パーティション分割されていないテーブル

パーティション分割されていないテーブルの場合、処理されたバイト数は次のように計算されます。

  • q = クエリでスキャンしたテーブルで、参照された列で処理された合計バイト数
  • t = クエリで列が参照されるか変更されるかにかかわらず、更新対象のテーブルに含まれるすべての列のクエリ開始時における合計バイト数。
DML ステートメント 処理されたバイト数
INSERT q
UPDATE q + t
DELETE q + t
MERGE INSERT 句のみがある場合: q
UPDATE 句または DELETE 句がある場合: q + t

パーティション分割テーブル

パーティション分割テーブルの場合、処理されたバイト数は次のように計算されます。

  • q' = クエリでスキャンしたすべてのパーティションで、参照された列で処理された合計バイト数。
  • t' = クエリで列が参照されるか変更されるかにかかわらず、更新された行の更新対象またはスキャン対象のパーティションに含まれるすべての列のクエリ開始時における合計バイト数。
DML ステートメント 処理されたバイト数
INSERT q'
UPDATE q' + t'
DELETE q' + t'
MERGE MERGE ステートメントに INSERT 句のみがある場合: q'
MERGE ステートメントに UPDATE 句または DELETE 句がある場合: q' + t'

DDL ステートメント

オンデマンド課金の場合、BigQuery がデータ定義言語(DDL)クエリで処理したバイト数に基づいて課金されます。

DDL ステートメント 処理されたバイト数
CREATE TABLE なし
CREATE TABLE ... AS SELECT ... クエリでスキャンしたテーブルによって参照されたすべての列で、処理された合計バイト数。
CREATE VIEW なし
DROP TABLE なし
DROP VIEW なし

スクリプト

オンデマンド課金の場合、BigQuery がスクリプトの実行中に処理したバイト数に基づいてスクリプト化の料金が課金されます。

スクリプティング固有のステートメントのタイプに適用される料金は次のとおりです。

  • DECLARE: DEFAULT 式で参照されるテーブルに対してスキャンされたバイトの合計。テーブルを参照していない DECLARE ステートメントには課金されません。
  • SET: 式で参照されるテーブルに対してスキャンされたバイトの合計。テーブルを参照していない SET ステートメントには課金されません。
  • IF: 条件式で参照されるテーブルに対してスキャンされたバイトの合計。テーブルを参照していない IF 条件式には課金されません。実行されていない IF ブロック内のステートメントには課金されません。
  • WHILE: 条件式で参照されるテーブルに対してスキャンされたバイトの合計。条件式のテーブルを参照していない WHILE ステートメントには課金されません。実行されていない WHILE ブロック内のステートメントには課金されません。
  • CONTINUE または ITERATE: 関連費用はありません。
  • BREAK または LEAVE: 関連費用はありません。
  • BEGIN または END: 関連費用はありません。

スクリプトの実行でストレージが使用されていても、一時テーブルに料金は発生しません。ただし、一時テーブルを作成、変更、照会するステートメントには通常の料金がかかります。

スクリプトが失敗すると、失敗までのステートメントの料金が引き続き適用されます。失敗したステートメントには課金されません。

スクリプティングの料金の例

次のサンプル スクリプトには、以下のすべてのステートメントの前に、ステートメントの実行で発生する費用やその有無について説明しているコメントが含まれています。

-- No cost, since no tables are referenced.
DECLARE x DATE DEFAULT CURRENT_DATE();
-- Incurs the cost of scanning string_col from dataset.table.
DECLARE y STRING DEFAULT (SELECT MAX(string_col) FROM dataset.table);
-- Incurs the cost of copying the data from dataset.big_table.  Once the
-- table is created, you are not charged for storage while the rest of the
-- script runs.
CREATE TEMP TABLE t AS SELECT * FROM dataset.big_table;
-- Incurs the cost of scanning column1 from temporary table t.
SELECT column1 FROM t;
-- No cost, since y = 'foo' doesn't reference a table.
IF y = 'foo' THEN
  -- Incurs the cost of scanning all columns from dataset.other_table, if
  -- y was equal to 'foo', or otherwise no cost since it is not executed.
  SELECT * FROM dataset.other_table;
ELSE
  -- Incurs the cost of scanning all columns from dataset.different_table, if
  -- y was not equal to 'foo', or otherwise no cost since it is not executed.
  UPDATE dataset.different_table
  SET col = 10
  WHERE true;
END IF;
-- Incurs the cost of scanning date_col from dataset.table for each
-- iteration of the loop.
WHILE x < (SELECT MIN(date_col) FROM dataset.table) DO
  -- No cost, since the expression does not reference any tables.
  SET x = DATE_ADD(x, INTERVAL 1 DAY);
  -- No cost, since the expression does not reference any tables.
  IF true THEN
    -- LEAVE has no associated cost.
    LEAVE;
  END IF;
  -- Never executed, since the IF branch is always taken, so does not incur
  -- a cost.
  SELECT * FROM dataset.big_table;
END WHILE;

クラスタ化テーブル

クラスタ化テーブルを使用すると、クエリで処理されないようにデータをプルーニングしてクエリの費用を抑えることができます。このプロセスはブロック プルーニングといいます。

ブロック プルーニング

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

クラスタ化テーブルにクエリを実行するときに、そのクエリにクラスタ化された列のフィルタが含まれている場合、BigQuery はフィルタ式とブロック メタデータを使用して、クエリでスキャンされるブロックをプルーニングします。これにより、BigQuery は関連するブロックのみをスキャンできます。

ブロックがプルーニングされると、スキャンの対象外となります。クエリで処理されたデータのバイト数を計算する際に、スキャンされたブロックのみが使用されます。クラスタ化テーブルに実行したクエリで処理されるバイト数は、スキャンされたブロック内で、クエリによって参照された各列から読み取られたバイト数の合計と等しくなります。

複数のフィルタを使用するクエリでクラスタ化テーブルが複数回参照された場合、BigQuery は、各フィルタで該当するブロックの列のスキャンに対して課金します。

クラスタ化テーブルの料金の例

ClusteredSalesData という名前のクラスタ化テーブルがあります。テーブルは timestamp 列で分割され、customer_id 列でクラスタ化されています。データは次のブロックセットに編成されます。

パーティション ID ブロック ID ブロック内の customer_id の最小値 ブロック内の customer_id の最大値
20160501 B1 10000 19999
20160501 B2 20000 24999
20160502 B3 15000 17999
20160501 B4 22000 27999

このテーブルに次のクエリを実行します。このクエリでは、customer_id 列のフィルタが含まれています。

SELECT
  SUM(totalSale)
FROM
  `mydataset.ClusteredSalesData`
WHERE
  customer_id BETWEEN 20000
  AND 23000
  AND DATE(timestamp) = "2016-05-01"

このクエリは次の処理を行います。

  • ブロック B2 と B4 の timestampcustomer_idtotalSale 列をスキャンします。
  • timestamp パーティショニング列に対する DATE(timestamp) = "2016-05-01" というフィルタ述語があるため、B3 ブロックをプルーニングします。
  • customer_id クラスタリング列に対する customer_id BETWEEN 20000 AND 23000 というフィルタ述語があるため、B1 ブロックをプルーニングします。

Cloud Storage でのカラム型のクエリ

外部データが ORC または Parquet に保存されている場合、請求対象のバイト数は、BigQuery が読み取る列に限定されます。外部データソースからのデータ型がクエリによって BigQuery のデータ型に変換されるので、読み取られたバイト数は BigQuery のデータ型のサイズに基づいて計算されます。データ型の変換の詳細については、次のページをご覧ください。