如何最好地处理写入App Engine中间表的大型查询结果

时间:2016-01-08 20:32:49

标签: google-app-engine google-bigquery

我们正在运行大型查询作业,我们达到了128M的响应大小,BigQuery引发了“响应太大而无法返回。请考虑在作业配置中将allowLargeResults设置为true”错误。

我们选择allowLargeResults方法来保持已经很复杂的SQL不变(而不是在这个级别上分块)。问题是处理写入中间表的结果的最佳方法是什么:

  • 将表导出到GCS,然后将使用偏移量处理响应文件块的任务排入GCS文件。这会引入GCS延迟,GCS文件维护(例如清理文件)和其他故障点(http错误/超时等)。

  • 还使用排队任务从中间表中查询块。这里的问题是块行的最佳方法是什么(有一种有效的方法可以做到这一点,例如,我们可以引用内部行号吗?)。我们可能最终会扫描每个块的整个表,因此这似乎比导出到GCS选项更昂贵。

这方面的经验和建议?

请注意,我们正在使用Google App Engine(Python)

谢谢!

3 个答案:

答案 0 :(得分:2)

请注意,BigQuery能够以块的形式导出数据 - 您可以请求与您拥有的工作块一样多的块。

来自https://cloud.google.com/bigquery/exporting-data-from-bigquery#exportingmultiple

如果您要求导出到:

['gs://my-bucket/file-name.json']

只要一个GCS文件小于1GB,您就会在一个GCS文件中获得导出。

如果您要求导出到:

['gs://my-bucket/file-name-*.json']

你会得到几个文件,每个文件都有一个总出口的块。导出超过1GB时非常有用。

如果您要求导出到:

['gs://my-bucket/file-name-1-*.json',
'gs://my-bucket/file-name-2-*.json',
'gs://my-bucket/file-name-3-*.json']

您将获得针对3名工人优化的出口。每个模式都会收到一系列导出的块,因此每个工作者都可以专注于自己的块。

答案 1 :(得分:2)

我知道https://cloud.google.com/bigquery/docs/reference/v2/tabledata/list会让您在不执行查询的情况下读取表格的块(产生数据处理费用)。

这使您可以并行读取查询结果,并将所有查询写入临时表ID,您可以将其传递给此函数并提供不同的范围(使用startIndex,maxResults)。

答案 2 :(得分:0)

目前尚不清楚“块处理”究竟是什么原因。如果你有一些complex SQL逻辑需要针对你的数据运行而且结果发生的时间大于当前的128MB限制 - 只需要使用allowLargeResults,然后以你需要使用它的方式消耗结果。 当然,你很可能有理由进行分块,但是它不被理解,因此回答有问题 另一个建议是不要在一个问题中提出很多问题 - 这使得回答很有问题,所以你很有机会不回答

Finally, my answer for the only question that is relatively clear (for me at least)
  

这里的问题是将行分块的最佳方法是什么(在那里   一种有效的方法,例如,我们有一个内部行号   可以参考?)。我们可能最终会扫描整个表格   因此,这似乎比导出到GCS选项

更昂贵

这取决于你的桌子创建的方式和时间!
如果你的表被加载为一个大负载 - 我不会一次又一次地看到避免表扫描的方式 如果表以增量和最近加载 - 你有机会享受所谓的Table Decoration(特别是你应该看看范围装饰器)

在BigQuery的早期阶段,人们期望有分区装饰器 - 这可以满足很多用户的需求 - 但它仍然无法使用,我不知道它们的计划是什么