运行交互式查询作业和批量查询作业

本文介绍如何运行交互式(按需)查询作业和批量查询作业。

所需权限

作业是 BigQuery 替您执行的操作,包括加载数据导出数据查询数据复制数据等。

使用 Console、经典版 BigQuery 网页界面或 CLI 加载、导出、查询或复制数据时,系统会自动创建、安排并运行作业资源。您还可以通过编程方式创建加载作业、导出作业、查询作业或复制作业。以编程方式创建作业后,BigQuery 会为您安排并运行相应作业。

作业可能需要很长时间才能完成,因此它们会异步执行,您可以对其进行轮询来了解其状态。用时较短的操作(例如列出资源或获取元数据)不由作业资源管理。

要运行查询作业,您需要具备 bigquery.jobs.create 权限。为保证查询作业成功完成,用户或组还必须有权访问包含查询所引用的表的数据集。

您可以通过授予以下任一预定义 IAM 角色来设置项目级层 bigquery.jobs.create 权限:

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

如果您向某个用户或群组授予了项目级层 bigquery.user 角色,则在默认情况下,系统不会向其授予该项目中任何数据集、表或视图的访问权限。具有 bigquery.user 角色的用户可以创建自己的数据集,还可对其已获访问权限的数据集运行查询作业。如果您分配了 bigquery.userbigquery.jobUser 角色,那么还必须分配对用户或群组需要访问但并非由其创建的每个数据集的访问权限控制

在分配对数据集的访问权限时,共有 3 个选项:

如果用户要运行查询,则至少需要具备“可查看”访问权限。

要详细了解 BigQuery 中的 IAM 角色,请参阅访问权限控制

运行交互式查询

默认情况下,BigQuery 运行交互式(按需)查询作业,也就是说,查询会尽快执行。交互式查询会计入并发速率限制和每日限额

查询结果始终保存到临时表或永久表中。您可以选择是否对现有表中的数据执行附加或覆盖操作,或者在不存在同名表的情况下是否新建一个表。

运行写入临时表的交互式查询的方法如下:

Console

  1. 在 GCP Console 中打开 BigQuery 网页界面。
    转到 BigQuery 网页界面

  2. 点击编写新查询

    编写新查询

  3. 查询编辑器文本区域中输入有效的 BigQuery SQL 查询。

  4. (可选)要更改数据处理位置,请点击更多,然后点击查询设置。在处理位置下,点击自动选择并选择数据的位置。最后,点击保存以更新查询设置。

  5. 点击运行

这会创建一个查询作业,将输出写入临时表中。

经典版界面

  1. 转到 BigQuery 网页界面。
    转到 BigQuery 网页界面

  2. 点击 Compose query

  3. New Query 文本区域中输入有效的 BigQuery SQL 查询。

  4. 点击 Show Options

  5. (可选)在处理位置部分,点击未指定并选择数据的位置

  6. 点击 Run Query

这会创建一个查询作业,将输出写入临时表中。

命令行

输入 bq query 命令,并包含您的查询文本。提供 --location 标志并将值设置为您的位置

您可以指定如下可选标志。此列表包含某些最常用的标志。如需查看 query 命令标志的完整列表,请参阅 bq 命令行工具参考中的 bq query

指定如下标志:

  • 指定 --destination_table 标志,以便根据查询结果创建一个永久表。要将查询结果写入非默认项目中的某个表,请按此格式将相应项目 ID 添加到数据集名称中:[PROJECT_ID]:[DATASET]。如果未指定 --destination_table,系统会生成一个查询作业,以便将输出写入到一个临时(缓存)表中。
  • 指定 --append_table 标志,以将查询结果附加到目标表。
  • 指定 --destination_kms_key 标志,以使用 Cloud KMS 密钥加密目标表数据。
  • 指定 --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 --location=US 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 --location=US 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'

如需了解详情,请参阅使用 bq 命令行工具

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
const {BigQuery} = require('@google-cloud/bigquery');

async function query() {
  // Queries the Shakespeare dataset with the cache disabled.

  // Create a client
  const bigqueryClient = new BigQuery();

  const query = `SELECT name
    FROM \`bigquery-public-data.usa_names.usa_1910_2013\`
    WHERE state = 'TX'
    LIMIT 100`;
  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 bigqueryClient.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));
}
query();

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 会将作业优先级更改为交互式

批量查询不会计入并发速率限制,因此您可以更轻松地同时启动多项查询。批量查询使用的资源与交互式(按需)查询相同。如果您使用固定费率价格,则批量查询和交互式查询将共用系统分配给您的槽。

运行批量查询的方法如下:

Console

  1. 在 GCP Console 中打开 BigQuery 网页界面。
    转到 BigQuery 网页界面

  2. 点击编写新查询按钮。

    编写新查询

  3. 查询编辑器文本区域中输入有效的 BigQuery SQL 查询。

  4. 点击更多按钮,然后点击查询设置

    查询设置

  5. 作业优先级部分,选择批量选项。

    批量执行

  6. (可选)在处理位置部分,点击未指定并选择数据的位置

  7. 点击保存以更新查询设置。

  8. 点击运行按钮。

经典版界面

  1. 转到 BigQuery 网页界面。
    转到 BigQuery 网页界面

  2. 点击 Compose query 按钮。

  3. New Query 文本区域中输入有效的 BigQuery SQL 查询。

  4. 点击 Show Options 按钮。

  5. Query Priority 部分中选择 Batch 选项。

  6. (可选)在处理位置部分,点击未指定并选择数据的位置

  7. 点击 Run query 按钮。

命令行

输入 bq query 命令,并包含您的查询文本。指定 --batch 标志以运行批量查询。提供 --location 标志并将值设置为您的位置

您可以指定如下可选标志。此列表包含某些最常用的标志。如需查看 query 命令标志的完整列表,请参阅 bq 命令行工具参考中的 bq query

指定如下标志:

  • 指定 --destination_table 标志,以便根据查询结果创建一个永久表。要将查询结果写入非默认项目中的某个表,请按此格式将相应项目 ID 添加到数据集名称中:[PROJECT_ID]:[DATASET]。如果未指定 --destination_table,系统会生成一个查询作业,以便将输出写入到一个临时(缓存)表中。
  • 指定 --append_table 标志,以将查询结果附加到目标表。
  • 指定 --destination_kms_key 标志,以使用 Cloud KMS 密钥加密目标表数据。
  • 指定 --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 --location=US 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 --location=US 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'

如需了解详情,请参阅使用 bq 命令行工具

API

要使用 API 运行查询,请插入新作业,并填充 jobs#configuration.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

试用此示例之前,请按照《BigQuery 快速入门:使用客户端库》中的 Java 设置说明进行操作。如需了解详情,请参阅 BigQuery Java API 参考文档

要运行批量查询,请将查询优先级设置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))

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
需要帮助?请访问我们的支持页面