使用快取查詢結果

這份文件說明如何在 BigQuery 中使用快取結果。

總覽

BigQuery 會將所有查詢結果寫入資料表,這份資料表可以由使用者明確指定 (目標資料表),也可以是暫時性的快取結果資料表。暫時性的快取結果資料表是依據不同的使用者和專案個別維護,不會向您收取儲存空間費用,但如果您將查詢結果寫入永久性資料表,則需支付該資料的儲存費用。

所有查詢結果 (包括互動式與批次查詢工作) 會以快取方式存放在暫時性資料表中約 24 小時,但也有一些例外

限制

使用查詢快取會受到下列限制:

  • 當您執行重複的查詢時,BigQuery 會嘗試重複使用快取的查詢結果。重複的查詢字詞必須與先前的查詢完全相同,系統才能從快取結果中擷取資料。
  • 如果查詢結果保留在快取結果資料表中,結果集必須小於回應大小上限。如要進一步瞭解如何管理大型結果集,請參閱傳回大量查詢結果
  • 您無法使用 DML 陳述式指定快取結果資料表。
  • 雖然目前的語意允許這類操作,但建議您不要將快取結果做為相依工作的輸入內容。舉例來說,請不要提交會從快取資料表擷取結果的查詢工作,請改為將您的結果寫入已命名的目標資料表。如要啟用簡易清除作業,部分功能 (例如資料集層級 defaultTableExpirationMs 屬性) 可能會在指定期限過後使資料自動過期。

定價與配額

如果查詢結果是擷取自快取結果資料表,系統傳回的工作統計資料屬性 statistics.query.cacheHit 值為 true,您就無須為這項查詢作業支付費用。雖然使用快取結果的查詢作業不收費,但仍適用 BigQuery 配額政策。除了降低成本以外,使用快取結果的查詢作業因為 BigQuery 不需計算結果集,可大幅加快執行速度。

查詢快取的例外狀況

在下列情況下,系統無法快取查詢結果:

  • 當您在工作設定、GCP Console、傳統網頁版 UI、指令列或 API 中指定目標資料表時
  • 在系統上次快取結果之後,已有參考資料表或邏輯檢視表經過異動
  • 查詢所參考的任一資料表最近收到串流資料插入 (有串流緩衝處理附加至資料表),即使沒有新增任何資料列
  • 查詢使用非絕對函式,比方日期和時間函式 (例如 CURRENT_TIMESTAMP()NOW()) 以及其他函式 (例如 CURRENT_USER()) 會根據查詢執行時間傳回不同的值
  • 使用萬用字元查詢多個資料表
  • 快取結果已過期;一般快取週期為 24 小時,但系統會盡量擷取快取結果,因此可能會更快失效
  • 查詢是針對外部資料來源執行

快取結果的儲存方式

當您執行查詢時,系統會在稱為「匿名資料集」的特殊資料集中建立一個暫時性的快取結果資料表。與從「身分與存取權管理」資源階層模型 (專案和機構權限) 繼承權限的一般資料集不同的是,匿名資料集的存取權僅限於資料集的擁有者。匿名資料集的擁有者是執行產生快取結果的查詢使用者。

建立匿名資料集時,系統會將匿名資料集的 bigquery.dataOwner 存取權明確授予執行查詢工作的使用者。bigquery.dataOwner 存取權僅允許執行查詢工作的使用者完全控制資料集,其中包括對匿名資料集裡的快取結果資料表的完整控管權。如果您打算共用查詢結果,請勿使用儲存在匿名資料集裡的快取結果。請改為將結果寫入已命名的目標資料表。

雖然執行查詢的使用者具備資料集和快取結果資料表的完整存取權,但建議您不要將這些資料做為相依工作的輸入內容。

匿名資料集的名稱會以底線開頭。這會將名稱隱藏於 GCP 主控台和傳統 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. 按一下 [Compose new query] (撰寫新查詢)

  3. 在「Query editor」(查詢編輯器) 文字區域中輸入有效的 SQL 查詢。

  4. 按一下 [More] (更多) 並選取 [Query settings] (查詢設定)

    查詢設定

  5. 在「Cache preference」(快取偏好) 下,取消勾選 [Use cached results] (使用快取的結果)

    快取的結果選項

傳統版 UI

  1. 前往傳統 BigQuery 網頁版 UI。
    前往 BigQuery 網頁版 UI

  2. 按一下 [Compose query] (撰寫查詢) 按鈕

  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 時,將使用查詢快取設為 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 函式執行查詢,可以將 copy 工作設定的 createDisposition 屬性設為 CREATE_NEVER,藉此強制讓無法使用快取結果的查詢工作失敗。

如果快取中沒有查詢結果,系統會傳回 NOT_FOUND 錯誤。

驗證是否使用快取

有兩種方式可供您判斷 BigQuery 傳回的結果是否使用快取:

  • 如果使用 GCP 主控台或傳統 BigQuery 網頁版 UI,結果字串不會包含已處理的位元組數資訊,但會顯示「cached」字樣。

    UI 中的快取指標

  • 如果使用 BigQuery API,系統會將查詢結果中的 cacheHit 屬性設為 true

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁