預估及控管費用

這個頁面說明在 BigQuery 中估算及控管費用的最佳做法。

BigQuery 的主要費用是運算費用 (用於查詢處理) 和儲存空間費用 (用於儲存在 BigQuery 中的資料)。BigQuery 提供兩種查詢處理計費模式:以量計價以容量為準的計費模式。每種模式都有不同的費用控管最佳做法。儲存在 BigQuery 的資料費用取決於為每個資料集設定的儲存空間帳單模型

瞭解 BigQuery 的運算定價

BigQuery 的運算價格有細微差異,會影響容量規劃和成本控管。

計費模式

在 BigQuery 中,隨選運算資源會依據 BigQuery 查詢的資料量 (以 TiB 為單位) 收費。

或者,如果是 BigQuery 的運算資源,您需要支付用於處理查詢的運算資源 (運算單元) 費用。如要使用這個模型,請為時段設定預留項目

預留功能具有下列特色:

  • 運算單元會分配到運算單元集區,方便您管理容量,並以適合貴機構的方式隔離工作負載。
  • 這些資源必須位於一個管理專案中,且受配額和限制規範。

容量定價模式提供多種版本,所有版本都提供即付即用選項,以時段小時計費。Enterprise 和 Enterprise Plus 版本也提供可選的一年或三年期運算單元承諾,與即付即用費率相比,可節省費用。

您也可以使用隨用隨付選項設定自動調度預訂。詳情請參閱下列文章:

限制每個模型的費用

使用隨選價格模式時,如要限制費用,唯一方法是設定專案層級或使用者層級的每日配額。不過,這些配額會強制設下上限,防止使用者執行超出配額限制的查詢。如要設定配額,請參閱「建立自訂查詢配額」。

使用運算單元預留項目時,您會指定預留項目可用的運算單元數量上限。您也可以購買運算單元承諾使用合約,在承諾使用期間享有折扣價。

您可以將預訂的基準設為 0,並將上限設為符合工作負載需求的設定,完全依需求使用版本。BigQuery 會自動調度資源,最多可調度至工作負載所需的配額數量,絕不會超過您設定的上限。詳情請參閱使用預留項目進行工作負載管理

控管查詢費用

如要控管個別查詢的費用,建議您先按照最佳做法調整查詢運算儲存空間

以下各節將說明其他最佳做法,可進一步控管查詢費用。

建立自訂查詢配額

最佳做法:使用自訂每日查詢配額,限制每日處理的資料量。

您可以設定自訂配額,指定每個專案或使用者每天處理的資料量上限,藉此管理費用。達到配額後,使用者就無法執行查詢。

如要設定自訂配額,您需要特定角色或權限。 如要設定配額,請參閱「配額與限制」。

詳情請參閱「限制各定價模式的費用」。

執行查詢前先查看預估費用

最佳做法:在執行查詢之前,請先檢查並估算需要支付多少費用。

如果採用以量計價模式,系統會根據查詢讀取的位元組數計費。如要在執行查詢之前估算費用,請使用:

使用查詢驗證工具

在 Google Cloud 主控台中輸入查詢時,查詢驗證工具會驗證查詢語法,並估算讀取的位元組數。您可以在 Pricing Calculator 中使用這項估算值來計算查詢費用。

  • 如果查詢無效,查詢驗證工具會顯示錯誤訊息。例如:

    Not found: Table myProject:myDataset.myTable was not found in location US

  • 如果查詢有效,查詢驗證工具會估算處理查詢所需的位元組數。例如:

    This query will process 623.1 KiB when run.

執行模擬測試

如要執行模擬測試,請按照下列步驟操作:

主控台

  1. 前往 BigQuery 頁面。

    前往 BigQuery

  2. 在查詢編輯器中輸入查詢。

    如果查詢有效,系統就會自動顯示勾號和查詢處理的資料量。如果查詢無效,則會顯示驚嘆號和錯誤訊息。

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 型別中,將 dryRun 設定為 true,然後提交查詢工作。

Go

在試行這個範例之前,請先按照 BigQuery 快速入門導覽課程:使用用戶端程式庫中的 Go 設定說明進行操作。詳情請參閱 BigQuery Go API 參考說明文件

如要向 BigQuery 進行驗證,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

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 := status.Err(); 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 參考說明文件

如要向 BigQuery 進行驗證,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

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 參考說明文件

如要向 BigQuery 進行驗證,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

// 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);
}

PHP

在試行這個範例之前,請先按照 BigQuery 快速入門導覽課程:使用用戶端程式庫中的 PHP 設定說明進行操作。詳情請參閱 BigQuery PHP API 參考說明文件

如要向 BigQuery 進行驗證,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

use Google\Cloud\BigQuery\BigQueryClient;

/** Uncomment and populate these variables in your code */
// $projectId = 'The Google project ID';
// $query = 'SELECT id, view_count FROM `bigquery-public-data.stackoverflow.posts_questions`';

// Construct a BigQuery client object.
$bigQuery = new BigQueryClient([
    'projectId' => $projectId,
]);

// Set job configs
$jobConfig = $bigQuery->query($query);
$jobConfig->useQueryCache(false);
$jobConfig->dryRun(true);

// Extract query results
$queryJob = $bigQuery->startJob($jobConfig);
$info = $queryJob->info();

printf('This query will process %s bytes' . PHP_EOL, $info['statistics']['totalBytesProcessed']);

Python

QueryJobConfig.dry_run 屬性設為 True。如果有提供模擬測試的查詢設定,則 Client.query() 一律會傳回已完成的 QueryJob

在試行這個範例之前,請先按照 BigQuery 快速入門導覽課程:使用用戶端程式庫中的 Python 設定說明進行操作。詳情請參閱 BigQuery Python API 參考說明文件

如要向 BigQuery 進行驗證,請設定應用程式預設憑證。 詳情請參閱「設定用戶端程式庫的驗證機制」。

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))

估算查詢費用

使用以量計價模式時,您可以計算處理的位元組數,估算執行查詢的費用。

以量計價查詢大小計算

如要計算各類查詢處理的位元組數,請參閱下列章節:

避免執行查詢來探索資料表資料

最佳做法:如果您只是想大致查看或預覽資料表中的資料,請勿使用查詢功能。

如要進行資料實驗或探索資料,可以使用資料表預覽選項免費查看資料,且不會影響配額。

BigQuery 支援下列資料預覽選項:

  • 在 Google Cloud 控制台的資料表詳細資料頁面中,按一下「預覽」分頁標籤,即可對資料進行取樣。
  • 在 bq 指令列工具中,使用 bq head 指令並指定要預覽的資料列數。
  • 在 API 中,使用 tabledata.list 從一組指定的資料列擷取資料表資料。
  • 請避免在非叢集資料表中使用 LIMIT。如果資料表未叢集化,LIMIT 子句不會降低運算費用。

限制每項查詢的計費位元組數

最佳做法:使用以量計價的定價模式時,請設定資料量計費上限,以控管查詢費用。

您可以使用計費位元組上限設定,限制針對查詢計費的位元組數。設定資料量計費上限後,系統會在查詢執行前預估查詢讀取的位元組數。如果預估的位元組數超過限制,查詢就會失敗,不會產生費用。

如果是叢集資料表,系統預估的查詢計費位元組數是上限,可能高於查詢執行後實際計費的位元組數。因此在某些情況下,即使實際計費位元組不會超過計費位元組上限設定,對叢集資料表執行的查詢仍可能失敗。

如果查詢因計費位元組上限設定而失敗,會傳回類似以下的錯誤:

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

設定資料量計費上限:

主控台

  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

JobConfigurationQueryQueryRequest 中設定 maximumBytesBilled 屬性。

避免在非叢集資料表中使用 LIMIT

最佳做法:對於非叢集資料表,請勿使用 LIMIT 子句做為費用控管的方法。

對於非叢集資料表,將 LIMIT 子句套用至查詢不會影響讀取的資料量。系統會收取您如查詢所指示,在完整資料表中讀取所有位元組的費用,即使查詢只傳回子集也是如此。使用叢集資料表時,LIMIT 子句可以減少掃描的位元組數,因為掃描作業會在掃描足夠的區塊以取得結果後停止。系統只會根據掃描的位元組數計費。

分階段具體化查詢結果

最佳做法:如有可能,請分階段具體化查詢結果。

如果您要建立大型、多階段的查詢,每次執行查詢時,BigQuery 都會讀取查詢要求的所有資料。系統會針對您每次執行查詢時讀取的所有資料收取相關費用。

因此,請改為分階段查詢,每個階段都會將查詢結果寫入目的地資料表來具體化查詢結果。查詢較小的目的地資料表會減少讀取的資料量並降低費用。儲存具體化結果的費用比處理大量資料的費用低很多。

控管工作負載費用

本節說明控管工作負載費用的最佳做法。工作負載是一組相關查詢。舉例來說,工作負載可以是每日執行的資料轉換管道、一組由一群業務分析師執行的資訊主頁,或一組由一群資料科學家執行的臨時查詢。

使用 Google Cloud 價格計算工具

最佳做法:使用 Google Cloud Pricing Calculator,根據預測用量估算 BigQuery 的整體月費。接著,您可以將這項預估值與實際費用進行比較,找出可最佳化的部分。

隨選

如要使用隨選計費模式,請按照下列步驟,在Google Cloud Pricing Calculator 中估算費用:

  1. 開啟Google Cloud Pricing Calculator
  2. 按一下「新增至估算值」
  3. 選取 BigQuery。
  4. 選取「隨選」做為服務類型
  5. 選擇要執行查詢的位置。
  6. 針對「Amount of data queried」(查詢的資料量),輸入來自模擬測試或查詢驗證工具的估算的讀取位元組數。
  7. 輸入「動態儲存」、「長期儲存」、「串流資料插入」和「串流讀取」的預估儲存空間用量。 您只需要根據資料集儲存空間計費模式,估算實體儲存空間或邏輯儲存空間。
  8. 預估費用會顯示在「費用明細」面板中。如要進一步瞭解預估費用,請按一下「開啟詳細檢視畫面」。你也可以下載及分享費用估算結果。

詳情請參閱以量計價一文。

版本

如要使用Google Cloud 定價計算機,估算採用以容量為準的定價模式搭配 BigQuery 版本時的費用,請按照下列步驟操作:

  1. 開啟Google Cloud Pricing Calculator
  2. 按一下「新增至估算值」
  3. 選取 BigQuery。
  4. 在「服務類型」中選取「版本」
  5. 選擇使用名額的位置。
  6. 選擇所需「版本」
  7. 選擇「運算單元數量上限」、「基準運算單元數量」、選用的「承諾」,以及「自動調度資源的預估使用率」
  8. 選擇資料的儲存位置。
  9. 輸入「動態儲存」、「長期儲存」、「串流資料插入」和「串流讀取」的預估儲存空間用量。 您只需要根據資料集儲存空間計費模式,估算實體儲存空間或邏輯儲存空間。
  10. 預估費用會顯示在「費用明細」面板中。如要進一步瞭解預估費用,請按一下「開啟詳細檢視畫面」。你也可以下載及分享費用估算結果。

詳情請參閱「以容量為準的定價」。

使用預留項目和承諾

最佳做法:使用 BigQuery 預留量和承諾用量控管費用。

詳情請參閱「限制各定價模式的費用」。

使用廣告空間預估工具

最佳做法:使用運算單元估算器,估算工作負載所需的運算單元數量。

BigQuery 運算單元估算工具可協助您根據過往成效指標管理運算單元容量。

此外,如果客戶使用隨選計費模式,在改用以容量為準的計費模式時,可以查看承諾和自動調度預留容量的規模建議,瞭解如何維持類似的效能。

取消不必要的長時間執行工作

如要釋出容量,請檢查長時間執行的工作,確認這些工作是否應繼續執行。如果沒有,請取消

使用資訊主頁查看費用

最佳做法:建立資訊主頁來分析 Cloud Billing 資料,以便監控及調整 BigQuery 用量。

您可將計費資料匯出至 BigQuery 並在 Looker Studio 等工具中以視覺化方式呈現。如需有關建立計費資訊主頁的教學課程,請參閱使用 BigQuery 和 Looker Studio 視覺化計費資訊 Google Cloud

使用帳單預算和快訊

最佳做法:使用 Cloud Billing 預算集中監控 BigQuery 費用。

透過 Cloud Billing 預算,您可以追蹤實際費用與預估費用之間的差異。設定預算金額後,您可以設定預算快訊門檻規則,用來觸發電子郵件通知。預算快訊電子郵件可協助您掌握 BigQuery 支出與預算的比較情形。

控管儲存空間費用

請參考這些最佳做法,盡量降低 BigQuery 儲存空間的費用。您也可以將儲存空間調整至最佳狀態,藉此提高查詢效能

使用長期儲存空間

最佳做法:使用長期儲存價格,降低舊資料的費用。

將資料載入 BigQuery 儲存空間後,將適用 BigQuery 的儲存空間定價。對於較舊的資料,您可以自動享有 BigQuery 長期儲存空間定價。

如果資料表連續 90 天未經修改,系統會自動將其儲存價格調降 50%。如果您有分區資料表,系統會將每個分區視為獨立的單位,判斷是否適用長期儲存價格,並遵守與非分區資料表相同的規則。

設定儲存空間計費模式

最佳做法:根據使用模式調整儲存空間計費模式。

BigQuery 支援使用邏輯 (未壓縮) 或實體 (已壓縮) 位元組,或兩者組合來計算儲存空間費用。為每個資料集設定的儲存空間計費模式會決定儲存空間價格,但不會影響查詢效能。

您可以透過 INFORMATION_SCHEMA 檢視畫面,根據用量模式判斷最適合的儲存空間計費模式。

避免覆寫資料表

最佳做法:使用實體儲存空間計費模式時,請避免重複覆寫資料表。

覆寫資料表時 (例如在批次載入工作中使用 --replace 參數,或使用 TRUNCATE TABLE SQL 陳述式),系統會在時空旅行和安全防護時間範圍內保留取代的資料。如果經常覆寫資料表,就會產生額外的儲存空間費用。

您可以改為在載入工作中使用 WRITE_APPEND 參數、MERGE SQL 陳述式,或使用 Storage Write API,將資料逐步載入資料表。

縮短時間回溯期

最佳做法:您可以根據需求縮短時間回溯視窗。

時空旅行視窗從預設值七天縮短,可減少從資料表刪除或變更資料的保留時間。只有在使用實體 (壓縮) 儲存空間計費模式時,才會收取時間旅行儲存空間費用。

時間回溯期是在資料集層級設定。您也可以使用設定,為新資料集設定預設時間回溯期。

為目的地資料表設定到期時間

最佳做法:如果您將大型查詢結果寫入目的地資料表,請使用預設資料表到期時間,等到您不再需要這些資料時,系統便會依照設定的時間來刪除資料。

在 BigQuery 儲存空間中保留大型結果集會產生費用。如果您不需要結果的擁有存取權,請使用預設資料表到期時間為您自動刪除資料。

將資料封存至 Cloud Storage

最佳做法:考慮將資料封存至 Cloud Storage。

您可以根據業務需求,將資料從 BigQuery 移至 Cloud Storage 進行封存。最佳做法是先考量長期儲存價格實體儲存空間計費模式,再從 BigQuery 匯出資料

後續步驟