執行互動式和批次查詢工作

本文件說明如何執行互動式 (隨選) 批次查詢工作。

所需權限

「工作」是 BigQuery 代表您執行的動作,包括載入資料匯出資料查詢資料複製資料

當您使用 Cloud Console、BigQuery 傳統網頁版 UI 或 CLI 來載入、匯出、查詢或複製資料時,系統會自動建立、排定及執行工作資源。您也可以透過程式建立載入、匯出、查詢或複製工作。透過程式來建立工作時,BigQuery 會為您排定和執行工作。

因為工作可能需要長時間才能完成,所以會非同步執行,而且可以輪詢其狀態。執行時間較短的動作 (如列出資源或取得中繼資料) 不會由工作資源管理。

您至少要具備 bigquery.jobs.create 權限,才能執行查詢工作。此外,如要順利完成查詢工作,您還必須具備相關權限以存取該查詢工作參照的資料表或檢視表所屬的資料集。如要進一步瞭解資料集存取權控管,請參閱控管資料集存取權一文。

以下是包含 bigquery.jobs.create 權限的預先定義 Cloud IAM 角色:

  • bigquery.user
  • bigquery.jobUser
  • bigquery.admin

此外,當具備 bigquery.datasets.create 權限的使用者建立資料集時,會獲得該資料集的 bigquery.dataOwner 存取權。bigquery.dataOwner 存取權可讓使用者查詢資料集中的資料表和檢視表。

如要深入瞭解 BigQuery 中的 Cloud IAM 角色,請參閱預先定義的角色與權限

執行互動式查詢

根據預設,BigQuery 會執行互動式 (隨選) 查詢工作,這表示查詢會盡快執行。互動式查詢會以您的並行頻率限制和每日上限計算。

查詢結果一律會儲存到臨時或永久資料表。 您可以選擇要在現有資料表中附加或覆寫資料,或是在沒有任何現有資料表使用同樣名稱的情況下,建立新的資料表。

如何執行寫入臨時資料表的互動式查詢:

主控台

  1. 在 Cloud Console 中開啟 BigQuery 網頁版 UI。
    前往 Cloud Console

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

    撰寫新查詢

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

  4. (選用) 如要變更資料處理位置,請按一下 [More] (更多),然後按一下 [Query settings] (查詢設定)。在「Processing location」(處理位置) 下,按一下 [Auto-select] (自動選取),然後選擇您資料的位置。最後,按一下 [Save] (儲存),更新查詢設定。

  5. 按一下 [Run] (執行)

這會建立一個查詢工作,將輸出寫入臨時資料表。

傳統版 UI

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

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

  3. 在「New Query」(新查詢) 文字區域中輸入有效的 SQL 查詢。

  4. 按一下 [Show Options] (顯示選項)

  5. (選用) 在「Processing Location」(處理位置) 中,按一下 [Unspecified] (未指定),然後選擇您資料的位置

  6. 按一下 [Run query] (執行查詢)

這會建立一個查詢工作,將輸出寫入臨時資料表。

CLI

輸入 bq query 指令並包含您的查詢文字。

(選用) 請提供 --location 旗標,並將其值設定為您的位置

您可以指定下列選用旗標。這個清單包含一些最常用的旗標。如需 query 指令旗標的完整清單,請參閱 bq 指令列工具參考資料中的 bq query

請指定:

  • --destination_table 旗標,根據查詢結果建立永久資料表。如要將查詢結果寫入不在預設專案內的資料表,請使用下列格式將專案 ID 新增至資料集名稱:project_id:dataset。如未指定 --destination_table,系統會產生將輸出寫入臨時 (快取) 資料表的查詢工作。
  • --append_table 旗標,將查詢結果附加至目的地資料表。
  • --destination_kms_key 旗標,以使用「金鑰管理服務」的金鑰來加密目的地資料表資料。
  • --use_legacy_sql=false 旗標,以使用標準 SQL 語法。您可以使用 .bigqueryrc 檔案為指令列工具設定預設語法
  • --label 旗標,以「key:value」格式將標籤套用至查詢工作。重複這個旗標即可指定多個標籤。
  • --max_rows-n 旗標,指定要在查詢結果中傳回的資料列數。
  • --maximum_bytes_billed 旗標,針對查詢指定會產生費用的位元組上限。查詢超出該上限就會失敗 (不會產生費用)。如果未指定,則會將產生費用的位元組上限設為專案預設值。
  • --udf_resource 旗標,載入並評估要做為使用者定義函式資源使用的程式碼檔案。您可以指定本機程式碼檔案的 Cloud Storage URI 或路徑。重複這個旗標即可指定多個檔案。

輸入下列指令可使用標準 SQL 語法執行互動式查詢:

bq --location=location query \
--use_legacy_sql=false \
'query'

其中:

  • 「location」是處理查詢的所在位置名稱,--location 是選用旗標。舉例來說,如果您在東京地區使用 BigQuery,就可以將該旗標的值設定為 asia-northeast1。您可以使用 .bigqueryrc 檔案設定位置的預設值。
  • 「query」是採用標準 SQL 語法的查詢。

範例:

輸入下列指令,將互動式查詢結果寫入 mydataset 中名為 mytable 的目的地資料表。該資料集位於預設專案中。查詢會從美國名稱資料公開資料集中擷取資料。

bq query \
--destination_table mydataset.mytable \
--use_legacy_sql=false \
'SELECT
  name,
  number
FROM
  `bigquery-public-data.usa_names.usa_1910_current`
WHERE
  gender = "M"
ORDER BY
  number DESC'

輸入下列指令,將互動式查詢結果寫入 mydataset 中名為 mytable 的目的地資料表。該資料集位於 myotherproject,而非預設專案中。查詢會從非分區資料表 (美國名稱資料公開資料集) 中擷取資料。

bq query \
--destination_table myotherproject:mydataset.mytable \
--use_legacy_sql=false \
'SELECT
  name,
  number
FROM
  `bigquery-public-data.usa_names.usa_1910_current`
WHERE
  gender = "M"
ORDER BY
  number DESC'

API

如要使用 API 執行查詢,請插入新工作,並填入 jobs#configuration.query 屬性。在工作資源jobReference 區段中,於 location 屬性指定您的位置。

呼叫 getQueryResults 來輪詢結果。持續輪詢,直到 jobComplete 等於 true 為止。檢查 errors 清單中的錯誤與警告。

C#

在嘗試這個範例之前,請至 BigQuery 快速入門:使用用戶端程式庫,按照 C# 設定說明進行操作。 詳情請參閱 BigQuery C# API 參考說明文件


using Google.Cloud.BigQuery.V2;
using System;

public class BigQueryQuery
{
    public void Query(
        string projectId = "your-project-id"
    )
    {
        BigQueryClient client = BigQueryClient.Create(projectId);
        string query = @"
            SELECT name FROM `bigquery-public-data.usa_names.usa_1910_2013`
            WHERE state = 'TX'
            LIMIT 100";
        BigQueryJob job = client.CreateQueryJob(
            sql: query,
            parameters: null,
            options: new QueryOptions { UseQueryCache = false });
        // Wait for the job to complete.
        job.PollUntilCompleted();
        // Display the results
        foreach (BigQueryRow row in client.GetQueryResults(job.Reference))
        {
            Console.WriteLine($"{row["name"]}");
        }
    }
}

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 name FROM `bigquery-public-data.usa_names.usa_1910_2013` " +
		"WHERE state = \"TX\" " +
		"LIMIT 100")
// 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)
}

Java

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

// BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();
String query = "SELECT corpus FROM `bigquery-public-data.samples.shakespeare` GROUP BY corpus;";
QueryJobConfiguration queryConfig = QueryJobConfiguration.newBuilder(query).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");
}

Node.js

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

// Import the Google Cloud client library using default credentials
const {BigQuery} = require('@google-cloud/bigquery');
const bigquery = new BigQuery();
async function query() {
  // Queries 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',
  };

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

PHP

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

use Google\Cloud\BigQuery\BigQueryClient;
use Google\Cloud\Core\ExponentialBackoff;

/** 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`';

$bigQuery = new BigQueryClient([
    'projectId' => $projectId,
]);
$jobConfig = $bigQuery->query($query);
$job = $bigQuery->startQuery($jobConfig);

$backoff = new ExponentialBackoff(10);
$backoff->execute(function () use ($job) {
    print('Waiting for job to complete' . PHP_EOL);
    $job->reload();
    if (!$job->isComplete()) {
        throw new Exception('Job has not yet completed', 500);
    }
});
$queryResults = $job->queryResults();

$i = 0;
foreach ($queryResults as $row) {
    printf('--- Row %s ---' . PHP_EOL, ++$i);
    foreach ($row as $column => $value) {
        printf('%s: %s' . PHP_EOL, $column, json_encode($value));
    }
}
printf('Found %s row(s)' . PHP_EOL, $i);

Python

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

# from google.cloud import bigquery
# client = bigquery.Client()

query = (
    "SELECT name FROM `bigquery-public-data.usa_names.usa_1910_2013` "
    'WHERE state = "TX" '
    "LIMIT 100"
)
query_job = client.query(
    query,
    # Location must match that of the dataset(s) referenced in the query.
    location="US",
)  # API request - starts the query

for row in query_job:  # API request - fetches results
    # Row values can be accessed by field name or index
    assert row[0] == row.name == row["name"]
    print(row)

Ruby

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

require "google/cloud/bigquery"

def query
  bigquery = Google::Cloud::Bigquery.new
  sql = "SELECT name FROM `bigquery-public-data.usa_names.usa_1910_2013` " +
        "WHERE state = 'TX' " +
        "LIMIT 100"

  # Location must match that of the dataset(s) referenced in the query.
  results = bigquery.query sql do |config|
    config.location = "US"
  end

  results.each do |row|
    puts row.inspect
  end
end

執行批次查詢

BigQuery 同時提供批次查詢。BigQuery 會代表您將每個批次查詢排入佇列,等到 BigQuery 共用資源集區中出現閒置資源,就會開始進行查詢。這通常會在幾分鐘內發生。如果 BigQuery 在 24 小時內未開始查詢,BigQuery 會將工作優先順序變更為互動式

批次查詢不會計入您的並行頻率限制,這樣就更容易一次開始多個查詢。批次查詢會使用與互動式 (隨選) 查詢相同的資源。如果您使用固定費率價格,批次查詢和互動式查詢會共用分配的運算單元數。

如何執行批次查詢:

主控台

  1. 在 Cloud Console 中開啟 BigQuery 網頁版 UI。
    前往 Cloud Console

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

    撰寫新查詢

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

  4. 按一下 [More] (更多) 按鈕,然後按一下 [Query settings] (查詢設定)。

    查詢設定

  5. 在「Job priority」(工作優先順序) 區段中選取 [Batch] (批次) 選項。

    批次執行

  6. (選用) 在「Processing Location」(處理位置) 中,按一下 [Unspecified] (未指定),然後選擇您資料的位置

  7. 按一下 [Save] (儲存) 以更新查詢設定。

  8. 按一下 [Run] (執行)

傳統版 UI

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

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

  3. 在「New Query」(新查詢) 文字區域中輸入有效的 BigQuery SQL 查詢。

  4. 按一下 [Show Options] (顯示選項) 按鈕。

  5. 在「Query Priority」(查詢優先順序) 區段中選取 [Batch] (批次) 選項。

  6. (選用) 在「Processing Location」(處理位置) 中,按一下 [Unspecified] (未指定),然後選擇您資料的位置

  7. 按一下 [Run query] (執行查詢) 按鈕。

CLI

輸入 bq query 指令並包含您的查詢文字。指定 -- batch 旗標以執行批次查詢。

(選用) 加上 --location 旗標,並該旗標值設為您的位置

您可以指定下列選用旗標。這個清單包含一些最常用的旗標。如需 query 指令旗標的完整清單,請參閱 bq 指令列工具參考資料中的 bq query

請指定:

  • --destination_table 旗標,根據查詢結果建立永久資料表。如要將查詢結果寫入不在預設專案內的資料表,請使用下列格式將專案 ID 新增至資料集名稱:project_id:dataset。如未指定 --destination_table,系統會產生將輸出寫入臨時 (快取) 資料表的查詢工作。
  • --append_table 旗標,將查詢結果附加至目的地資料表。
  • --destination_kms_key 旗標,以使用「金鑰管理服務」的金鑰來加密目的地資料表資料。
  • --use_legacy_sql=false 旗標,以使用標準 SQL 語法。您可以使用 .bigqueryrc 檔案為指令列工具設定預設語法
  • --label 旗標,以「key:value」格式將標籤套用至查詢工作。重複這個旗標即可指定多個標籤。
  • --max_rows-n 旗標,指定要在查詢結果中傳回的資料列數。
  • --maximum_bytes_billed 旗標,針對查詢指定會產生費用的位元組上限。查詢超出該上限就會失敗 (不會產生費用)。如果未指定,則會將產生費用的位元組上限設為專案預設值。
  • --udf_resource 旗標,載入並評估要做為使用者定義函式資源使用的程式碼檔案。您可以指定本機程式碼檔案的 Cloud Storage URI 或路徑。重複這個旗標即可指定多個檔案。

輸入下列指令,使用標準 SQL 語法執行批次查詢:

bq --location=location query \
--batch \
--use_legacy_sql=false \
'query'

其中:

  • 「location」是處理查詢的所在位置名稱,--location 是選用旗標。舉例來說,如果您在東京地區使用 BigQuery,就可以將該旗標的值設定為 asia-northeast1。您可以使用 .bigqueryrc 檔案設定位置的預設值。
  • 「query」是採用標準 SQL 語法的查詢。

範例:

輸入下列指令,將批次查詢結果寫入 mydataset 中名為 mytable 的目的地資料表。該資料集位於預設專案中。查詢會從美國名稱資料公開資料集中擷取資料。

bq query \
--batch \
--destination_table mydataset.mytable \
--use_legacy_sql=false \
'SELECT
  name,
  number
FROM
  `bigquery-public-data.usa_names.usa_1910_current`
WHERE
  gender = "M"
ORDER BY
  number DESC'

輸入下列指令,將批次查詢結果寫入 mydataset 中名為 mytable 的目的地資料表。該資料集位於 myotherproject,而非預設專案中。查詢會從非分區資料表 (美國名稱資料公開資料集) 中擷取資料。

bq query \
--batch \
--destination_table myotherproject:mydataset.mytable \
--use_legacy_sql=false \
'SELECT
  name,
  number
FROM
  `bigquery-public-data.usa_names.usa_1910_current`
WHERE
  gender = "M"
ORDER BY
  number DESC'

API

如要使用 API 執行查詢,請插入新工作並填入 query 工作設定屬性。(選用) 請前往工作資源jobReference 區段,並在 location 屬性中指定您的位置。

填入查詢工作屬性時,請加入 configuration.query.priority 屬性,並將值設為 BATCH

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")
	// Build an aggregate table.
	q := client.Query(`
		SELECT
  			corpus,
  			SUM(word_count) as total_words,
  			COUNT(1) as unique_words
		FROM ` + "`bigquery-public-data.samples.shakespeare`" + `
		GROUP BY corpus;`)
	q.Priority = bigquery.BatchPriority
	q.QueryConfig.Dst = client.Dataset(dstDatasetID).Table(dstTableID)

	// Start the job.
	job, err := q.Run(ctx)
	if err != nil {
		return err
	}
	// Job is started and will progress without interaction.
	// To simulate other work being done, sleep a few seconds.
	time.Sleep(5 * time.Second)
	status, err := job.Status(ctx)
	if err != nil {
		return err
	}

	state := "Unknown"
	switch status.State {
	case bigquery.Pending:
		state = "Pending"
	case bigquery.Running:
		state = "Running"
	case bigquery.Done:
		state = "Done"
	}
	// You can continue to monitor job progress until it reaches
	// the Done state by polling periodically.  In this example,
	// we print the latest status.
	fmt.Printf("Job %s in Location %s currently in state: %s\n", job.ID(), job.Location(), state)

Java

如要執行批次查詢,請將查詢優先順序設定QueryJobConfiguration.Priority.BATCH (當建立 QueryJobConfiguration 時)。

// BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();
String query = "SELECT corpus FROM `bigquery-public-data.samples.shakespeare` GROUP BY corpus;";
QueryJobConfiguration queryConfig =
    QueryJobConfiguration.newBuilder(query)
        // Run at batch priority, which won't count toward concurrent rate
        // limit.
        .setPriority(QueryJobConfiguration.Priority.BATCH)
        .build();

// Location must match that of the dataset(s) referenced in the query.
JobId jobId = JobId.newBuilder().setRandomJob().setLocation("US").build();
String jobIdString = jobId.getJob();

// API request - starts the query.
bigquery.create(JobInfo.newBuilder(queryConfig).setJobId(jobId).build());

// Check on the progress by getting the job's updated state. Once the state
// is `DONE`, the results are ready.
Job queryJob = bigquery.getJob(
    JobId.newBuilder().setJob(jobIdString).setLocation("US").build());
System.out.printf(
    "Job %s in location %s currently in state: %s%n",
    queryJob.getJobId().getJob(),
    queryJob.getJobId().getLocation(),
    queryJob.getStatus().getState().toString());

Python

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

# from google.cloud import bigquery
# client = bigquery.Client()

job_config = bigquery.QueryJobConfig()
# Run at batch priority, which won't count toward concurrent rate limit.
job_config.priority = bigquery.QueryPriority.BATCH
sql = """
    SELECT corpus
    FROM `bigquery-public-data.samples.shakespeare`
    GROUP BY corpus;
"""
# Location must match that of the dataset(s) referenced in the query.
location = "US"

# API request - starts the query
query_job = client.query(sql, location=location, job_config=job_config)

# Check on the progress by getting the job's updated state. Once the state
# is `DONE`, the results are ready.
query_job = client.get_job(
    query_job.job_id, location=location
)  # API request - fetches job
print("Job {} is currently in state {}".format(query_job.job_id, query_job.state))