管理查询输出

在评估输出数据时,请考虑查询写入的字节数。向结果集写入了多少字节?您是否适当限制了写入的数据量?是否重复写入了相同数据?查询写入的数据量会影响查询性能 (I/O)。如果要将结果写入永久性(目标)表,则写入的数据量还会产生费用。

以下最佳做法就如何控制输出数据提供了指南。

避免重复的联接和子查询

最佳做法:避免反复联接相同的表和使用相同的子查询。

如果您要反复联接相同的表,请考虑修改您的架构。与反复联接数据相比,使用嵌套的重复数据来表示相应关系可能会获得更高性能。嵌套的重复数据可以降低联接所需的通信带宽对性能的影响,还可以为您节省因反复读写相同数据而产生的 I/O 费用。如需了解详情,请参阅使用嵌套和重复字段

同样,重复相同的子查询也会因重复的查询处理而影响性能。如果您要在多个查询中使用相同的子查询,请考虑将子查询结果具体化为一个表。然后在查询中使用已具体化的数据。

将子查询结果具体化可以改善性能,并减少 BigQuery 读写的总数据量。已具体化数据的存储费用远远低于重复的 I/O 和查询处理给性能带来的影响。

仔细考虑大型结果集的具体化

最佳做法:仔细考虑如何将大型结果集具体化为一个目标表。写入大型结果集会影响性能和成本。

BigQuery 将缓存结果大小上限设为大约 10 GB(压缩后大小)。如果查询返回的结果数据量超过了此限制,通常会导致以下错误:Response too large

从包含大量数据的表中选择大量字段时,常常会发生这种错误。如果 ETL 样式的查询在未减少或汇总数据的情况下对数据进行规范化,写入缓存结果时也会发生问题。

您可以通过以下方式克服对缓存结果大小的限制:

  • 使用过滤条件限制结果集
  • 使用 LIMIT 子句减少结果集中的数据量,尤其是在使用 ORDER BY 子句时
  • 将输出数据写入目标表

请注意,将非常大的结果集写入目标表会影响查询性能 (I/O)。此外,存储目标表会产生少量费用。您可以利用数据集的默认表过期时间自动删除大型目标表。如需了解详情,请参阅存储最佳做法中的使用过期时间设置

搭配大型排序使用 LIMIT 子句

最佳做法:如果您要对大量值进行排序,可使用 LIMIT 子句。

使用 ORDER BY 子句写入查询结果可能会导致 Resources exceeded 错误。因为最终排序必须在单个槽上完成,所以如果您尝试对非常大的结果集进行排序,则最终排序可能会超出用于处理数据的槽所能承受的数量。如果您要使用 ORDER BY 子句,也请使用 LIMIT 子句。

例如,以下查询在对非常大的结果集进行排序时会引发 Resources exceeded 错误。该查询按 Wiki1B 表中的 title 列排序。title 列包含数百万个值。

SELECT
  title
FROM
  `bigquery-samples.wikipedia_benchmark.Wiki1B`
ORDER BY
  title

要移除此错误,请使用如下查询:

SELECT
  title
FROM
  bigquery-samples.wikipedia_benchmark.Wiki1B
ORDER BY
  title DESC
LIMIT
  1000
此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

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