优化加载作业

本文档中介绍的策略和最佳实践可帮助您优化将数据批量加载或流式加载到 BigQuery 的过程,从而避免达到每个表每天的加载作业数量上限

由于加载作业的限制是固定的,无法增加,因此您应通过表分区等方法来优化表结构,从而优化加载作业;或者通过批量加载或流式传输等方法来管理加载作业。

表格操作配额的运作方式

无论修改是附加数据、更新数据还是截断表,每个项目每天对每个表进行的 BigQuery 表修改次数上限都是固定的。此限制包括向目标表添加数据或覆盖目标表的所有加载作业复制作业查询作业的总和。

加载作业具有补充速率。如果超出表操作限制或其补充速率,加载作业将失败并显示 quotaExceeded 错误。项目级每日加载作业数上限会在 24 小时的滚动时段内恢复。加载作业完成后,可用配额会减少。然后,配额会在接下来的 24 小时内逐渐恢复。失败的加载作业仍会计入每个表和每个项目的配额。如需详细了解加载作业限制,请参阅加载作业

对于分区表,系统会应用单独的分区表修改次数限制,取代标准表限制。

为避免超出每日表操作次数限制,请将操作分散到 24 小时内。例如,如果您执行 25 次更新,每次更新包含 60 项操作,那么您大约每 58 分钟可以运行 60 项操作。此方法有助于您达到每日限额。如需监控表更新,请参阅 BigQuery INFORMATION_SCHEMA 视图

不计入配额的表操作

更新表信息(元数据)和使用 DML 语句不会计入每日表修改次数上限。此排除项同时适用于标准表和分区表。

您的项目可以运行无限数量的 DML 语句。虽然 DML 语句之前会计入每日表修改次数,并且即使达到上限也不会受到限制,但现在已不再如此。

流式插入也会修改表,但受其自己的特定配额限制。

避免达到表操作限制的加载策略

为了不超过 BigQuery 的每日表操作次数限制,请考虑以下最佳实践:

  • 执行较少次数的较大写入,而不是多次较小的写入。
  • 尽量减少每天向最终生产表执行的单独写入作业。

如需使用这些最佳实践,请将数据批量加载或流式传输到 BigQuery 中。您选择的加载方法取决于您是否需要实时加载大量数据,或者是否不考虑实时加载。以下各部分将详细介绍批量加载和数据流式传输,包括可用于每种方法的工具和服务。

批量加载

为了不超过 BigQuery 的每个项目每日加载限额,请批量处理大量数据,并使用较少的作业将其加载到 BigQuery 中。以下部分介绍了可用于批量加载数据的几种方法。

为每个作业加载更多数据

您可以收集数据,然后使用单个大型作业将其加载到 BigQuery 中,而不是在每次有新信息可用时都将数据发送到 BigQuery。

例如,您可以等待文件(例如 CSV 或 JSON 文件)中累积了数千行数据,然后再运行一个加载作业,将所有数据附加到表中,而不是每隔几行数据就运行一个单独的加载作业。即使作业包含更多数据,此操作也只会计为一次表操作。您可以在加载作业中使用通配符来批量处理文件。借助通配符,您可以选择目录中的一批文件,以便在单个加载作业中加载多个文件。

以下示例展示了如何在 bq load 命令或 SQL LOAD DATA 查询中使用通配符。

bq

以下示例展示了如何使用 bq load 命令将 CSV 数据从 Cloud Storage 加载到名为 my_target_table 的 BigQuery 表中。如需选择多个源文件名,请在命令中使用通配符。AUTODETECT 标志可根据 Cloud Storage 中的源数据自动确定表架构,并且支持使用通配符 (*) 将符合特定命名模式的多个文件加载到 BigQuery 表中。

bq load \
  --source_format=CSV \
  --autodetect \
  --project_id=PROJECT_ID \
  DATASET_NAME.TABLE_NAME \
  "gs://BUCKET_NAME/OBJECT_PATH_WILDCARD"

替换以下内容:

  • PROJECT_ID:您的 Google Cloud 项目的 ID。
  • DATASET_NAME:您要将数据加载到的 BigQuery 数据集的名称。
  • TABLE_NAME:您要将数据加载到的 BigQuery 表的名称。
  • BUCKET_NAME:包含源文件的 Cloud Storage 存储桶的名称。
  • OBJECT_PATH_WILDCARD:Cloud Storage 存储桶中 CSV 文件的路径。添加通配符 (*) 以匹配多个文件。例如,字符串 gs://my-bucket/path/to/data/my_prefix_*.csv 使用通配符 * 加载 gs://my-bucket/path/to/data/ 中以 my_prefix_ 开头且以 .csv 结尾的所有文件。

详情请参阅以下内容:

SQL

以下示例展示了如何使用 SQL LOAD DATA 查询将 CSV 数据从 Cloud Storage 存储桶加载到 BigQuery 表中。如需选择多个源文件名,请在命令中使用通配符。

LOAD DATA INTO
DATASET_NAME.TABLE_NAME
FROM FILES (
  format = 'SOURCE_FORMAT',
  uris = ['gs://BUCKET_NAME/OBJECT_PATH_WILDCARD]
  );

替换以下内容:

  • DATASET_NAME:您要将数据加载到的 BigQuery 数据集的名称。
  • TABLE_NAME:您要将数据加载到的 BigQuery 表的名称。
  • SOURCE_FORMAT 用于设置源文件的类型,例如 CSVJSON。在此示例中,请使用 CSV
  • BUCKET_NAME:包含源文件的 Cloud Storage 存储桶的名称。
  • OBJECT_PATH_WILDCARD:Cloud Storage 存储桶中 CSV 文件的路径。添加通配符 (*) 以匹配多个文件。例如,字符串 gs://my-bucket/path/to/data/my_prefix_*.csv 使用通配符 * 加载 gs://my-bucket/path/to/data/ 中以 my_prefix_ 开头且以 .csv 结尾的所有文件。

如需了解详情,请参阅 GoogleSQL 中的加载语句

使用 BigQuery Storage Write API 进行批量加载

如需将批量数据加载到 BigQuery 中,一种方法是使用 Google API 客户端库直接从应用中使用 Storage Write API。

Storage Write API 可优化数据加载,以确保不超过表限制。对于大容量实时流式传输,请使用 PENDING 流,而不是 COMMITTED 流。使用 PENDING 数据流时,API 会暂时存储记录,直到您提交数据流为止。

如需查看有关使用 Storage Write API 批量加载数据的完整示例,请参阅使用 Storage Write API 批量加载数据

使用 Dataflow 进行批量加载

如果您想使用数据流水线将数据流式传输、转换并写入 BigQuery,可以使用 Dataflow。您创建的数据流水线会从受支持的来源(例如 Pub/Sub 或 Apache Kafka)读取数据。您还可以使用 BigQueryIO 连接器创建 Dataflow 流水线,该连接器使用 Storage Write API 实现高性能数据流式处理和“正好一次”语义。

如需了解如何使用 Dataflow 将数据批量加载到 BigQuery,请参阅将数据从 Dataflow 写入 BigQuery

数据流

如需加载大量频繁更新的数据,建议您将数据流式传输到 BigQuery 中。借助数据流式传输,新数据会从客户端应用持续写入 BigQuery,这种策略可避免因运行过多加载作业而达到限制。以下部分介绍了将数据流式传输到 BigQuery 的几种方法。

使用 Storage Write API 流式传输数据

使用 Storage Write API 以极低的延迟将记录实时流式传输到 BigQuery 中。Storage Write API 提供了一种高效的流式传输协议,可提供高级功能,例如正好一次传送语义、架构更新检测和流式变更数据捕获 (CDC) 更新/插入。此外,您每月可以免费注入高达 2 TiB 的数据。

如需了解如何使用 Storage Write API,请参阅使用 Storage Write API 流式传输数据

使用 Dataflow 流式传输数据

使用 Dataflow 创建从受支持的来源(例如 Pub/Sub 或 Apache Kafka)读取数据的流水线。然后,这些流水线会转换数据并将其写入 BigQuery 作为目标。您可以使用 BigQueryIO 连接器(使用 Storage Write API)创建 Dataflow 流水线。

如需了解如何使用 Dataflow 将数据流式传输到 BigQuery,请参阅将数据从 Dataflow 写入 BigQuery

管理用于加载的表的最佳实践

除了将数据批量加载或流式传输到 BigQuery 中之外,您还可以通过以下方式管理表,以优化数据注入。

使用分区表

表分区是一种在 BigQuery 中管理大型表的强大技术,尤其是在您需要频繁执行数据加载操作时。您可以根据日期、时间戳或整数将表划分为更小、更易于管理的段,从而显著提高表性能和成本效益。

对于数据加载,分区的主要优势在于,BigQuery 的每日表操作配额适用于分区级层,而不是表级层。对于分区表,分区修改有单独的更高限制,取代了标准表限制。分区表的限制可大幅增加您每天可运行的加载作业数量,而不会达到配额限制。

一种常见且非常有效的策略是批量加载每日数据。例如,您可以将 2025-09-18 的所有当天数据收集到临时过渡表中。然后,在一天结束时,您运行一个作业,将这些数据加载到主生产表中当天的特定分区中。由于 BigQuery 只与单个分区的数据进行交互,因此这种方法可让您的数据井井有条,并使加载操作更快、更经济实惠。

虽然强烈建议对不断增长的大型表进行分区,但如果分区始终小于 10 GB,最好避免分区。如需了解详情,请参阅何时使用分区

如需详细了解可用的不同分区方法(例如时间单位分区和整数范围分区),请参阅分区表的类型

利用内置的指数退避算法、截断和抖动功能

内置的指数退避和重试是一种错误处理方法,可帮助您的应用在操作暂时失败时顺利恢复。此类失败可能包括速率限制错误 (rateLimitExceeded) 或短暂的网络问题 (unavailable)。

在可靠的系统中,从客户端队列中获取任务的工作人员也会使用指数退避算法和重试。它们在调用 BigQuery 时会执行此操作,从而创建两层保护。

例如,Python 的官方 google-cloud-bigquery-storage 库包含内置的指数退避算法重试逻辑。此逻辑用于处理临时 gRPC 错误,例如 UNAVAILABLE。在大多数情况下,您无需自行编写此重试代码。client.append_rows() 调用会自动处理这些重试。

这种内置处理是使用官方客户端库的一项显著优势。您只需处理无法重试的错误,例如 INVALID_ARGUMENT(表示存在架构不匹配问题)。