使用数据操纵语言 (DML) 转换数据
借助 BigQuery 数据操纵语言 (DML),您可以在 BigQuery 表中更新、插入和删除数据。
执行 DML 语句的过程与执行 SELECT
语句的过程相同,但必须符合以下条件:
- 您必须使用 GoogleSQL。如需启用 GoogleSQL,请参阅切换 SQL 方言。
- 您无法为查询指定目标表。
如需查看 BigQuery DML 语句列表及其使用示例,请参阅 GoogleSQL 中的数据操纵语言语句。如需详细了解如何计算 DML 语句处理的字节数,请参阅按需查询大小计算。
并发作业数
BigQuery 管理用于添加、修改或删除表中各行的 DML 语句的并发。
INSERT DML 并发
在任意 24 小时内,前 1500 个 INSERT
语句在提交后便立即运行。达到此限制后,写入表的 INSERT
语句的并发限制为 10。其他 INSERT
语句会添加到 PENDING
队列中。在任何给定时间内,最多可在表中将 100 个 INSERT
语句排入队列。INSERT
语句完成后,下一个 INSERT
语句会从队列中移除并运行。
如果您必须更频繁地运行 DML INSERT
语句,请考虑使用 Storage Write API 将数据流式插入到表中。
UPDATE、DELETE、MERGE DML 并发
UPDATE
、DELETE
和 MERGE
DML 语句称为变更型 DML 语句。如果您在某个表上提交了一个或多个变更型 DML 语句,而该表上有其他变更型 DML 作业仍在运行(或待处理),则 BigQuery 最多并发运行 2 个作业,之后最多可以将 20 个作业加入队列作为 PENDING
作业。当上一个运行的作业完成时,下一个 PENDING 作业将移出队列并运行。加入队列的变更型 DML 语句所共享的每个表的最大队列长度为 20。其他超出每个表的最大队列长度的语句会失败,并显示错误消息:Resources
exceeded during query execution: Too many DML statements outstanding against
table PROJECT_ID:TABLE, limit is 20.
排队时间超过 6 小时的互动优先级 DML 作业会失败,并显示以下错误消息:
DML statement has been queued for too long
DML 语句冲突
在表上并发运行的 DML 语句会在语句尝试更改同一分区时导致 DML 语句冲突。只要不修改同一分区,语句就会成功。BigQuery 最多尝试重新运行失败的语句三次。
在表中插入行的
INSERT
DML 语句不会与任何其他并发运行的 DML 语句发生冲突。只要
MERGE
DML 语句仅插入行并且不会删除或更新任何现有行,就不会与其他并发运行的 DML 语句发生冲突。这可能包括具有UPDATE
或DELETE
子句的MERGE
语句,前提是查询运行时未调用这些子句。
精细 DML
精细 DML 是一项性能增强功能,旨在优化 UPDATE
、DELETE
和 MERGE
语句(也称为变更型 DML 语句)的执行。如果未启用精细 DML,系统会在文件组一级执行更改,这可能会导致数据重写效率低下。精细 DML 引入了一种更精细的方法,旨在减少需要重写的数据量,并减少总体槽用量。
如果您有意向将项目注册到精细化 DML 预览版,请填写 BigQuery 精细化 DML 注册表单。系统会根据对工作负载的评估,选择性地注册项目。
启用精细 DML
如需启用精细 DML,请在运行 CREATE TABLE
或 ALTER TABLE
DDL 语句时将 enable_fine_grained_mutations
表选项设置为 TRUE
。
如需使用精细的 DML 创建新表,请使用 CREATE TABLE
语句:
CREATE TABLE mydataset.mytable ( product STRING, inventory INT64) OPTIONS(enable_fine_grained_mutations = TRUE);
如需使用精细 DML 更改现有表,请使用 ALTER TABLE
语句:
ALTER TABLE mydataset.mytable SET OPTIONS(enable_fine_grained_mutations = TRUE);
将 enable_fine_grained_mutations
选项设置为 TRUE
后,系统会启用精细 DML 功能并使用现有的 DML 语句语法来运行变更型 DML 语句。
如需在表上停用精细 DML,请使用 ALTER TABLE
DDL 语句将 enable_fine_grained_mutations
设置为 FALSE
。
价格
为表启用精细 DML 可能会产生额外的 BigQuery 存储费用,用于存储与精细 DML 操作关联的额外更改元数据。实际费用取决于修改的数据量,但在大多数情况下,与表本身的大小相比,该费用应该可以忽略不计。
配置为使用reservations的项目使用槽来处理精细的 DML 语句,包括表或更改元数据的任何后台处理。
已删除的数据注意事项
精细 DML 操作会以离线方式处理已删除的数据。
在没有 BACKGROUND
分配的情况下执行精细 DML 操作的项目会使用按需价格删除数据。在这种情况下,系统会使用内部 BigQuery 资源定期处理已删除的数据。
使用 BACKGROUND
分配执行精细 DML 操作的项目会使用槽处理已删除的数据,并且受已配置的预留的资源可用性影响。如果已配置的预留中没有足够的资源,则处理已删除的数据的时间可能会超出预期。
限制
启用了精细 DML 的表受到以下限制:
- 您无法使用
tabledata.list
方法从启用了精细 DML 的表中读取内容。而是改用 Storage Read API 使用 API 读取表记录。 - 您无法为启用了精细 DML 的表创建表快照或表克隆。
- 您无法对复制的数据集中表启用精细 DML,也无法复制包含已启用精细 DML 的表的数据集。
- 在多语句事务中执行的 DML 语句不会使用精细 DML 进行优化。
最佳做法
为获得最佳性能,Google 建议您使用以下模式:
避免提交大量个别行更新或插入操作。而是尽可能将 DML 操作组合在一起。如需了解详情,请参阅更新或插入单行的 DML 语句。
如果更新或删除操作通常发生在旧数据或者特定日期范围内,请考虑对您的表进行分区。通过分区可确保仅针对表中的特定分区进行更改。
如果每个分区中的数据量较小,并且每次更新都会修改大部分分区,请避免对分区表进行分区。
如果您经常更新对应的一列或多列位于较小范围值的行,请考虑使用聚簇表。聚簇操作可确保仅对一组特定的块进行更改,从而减少需要读取和写入的数据量。以下是针对一系列列值进行过滤的
UPDATE
语句的示例:UPDATE mydataset.mytable SET string_col = 'some string' WHERE id BETWEEN 54 AND 75;
以下是针对一小部分列值进行过滤的类似示例:
UPDATE mydataset.mytable SET string_col = 'some string' WHERE id IN (54, 57, 60);
在以下情况下,请考虑对
id
列进行聚簇。如果您需要 OLTP 功能,请考虑使用 Cloud SQL 联合查询,使 BigQuery 能够查询 Cloud SQL 中的数据。
如需了解优化查询性能的最佳实践,请参阅优化查询性能简介。
限制
每个 DML 语句都会启动一个隐式事务,这表示在每个 DML 语句成功结束时,系统会自动提交该语句所做的更改。
最近使用
tabledata.insertall
流式传输方法写入的行无法使用数据操纵语言 (DML) 修改,例如UPDATE
、DELETE
、MERGE
或TRUNCATE
语句。最近的写入是指最近 30 分钟内发生的写入。表中的所有其他行仍可以使用UPDATE
、DELETE
、MERGE
或TRUNCATE
语句进行修改。流式插入的数据最多可能需要 90 分钟才能用于复制操作。或者,可以使用
UPDATE
、DELETE
或MERGE
语句修改最近使用 Storage Write API 写入的行。如需了解详情,请参阅对最近流式插入的数据使用数据操纵语言 (DML)。MERGE
语句不支持when_clause
、search_condition
、merge_update_clause
或merge_insert_clause
中的关联子查询。包含 DML 语句的查询不能将通配符表用作查询的目标。例如,通配符表可用于
UPDATE
查询的FROM
子句,但不能用作UPDATE
操作的目标。