查询在没有目标表的情况下工作,但由于目标表“超出资源”而失败
Posted
技术标签:
【中文标题】查询在没有目标表的情况下工作,但由于目标表“超出资源”而失败【英文标题】:Query works without destination table, but fails with destination table "resources exceeded" 【发布时间】:2020-03-27 08:33:38 【问题描述】:我有一个查询,它产生大约 2000 万行,需要按时间戳 DESC 排序。当我使用设置“将查询结果保存在临时表中”时,查询工作,但是当我设置目标表时,查询失败并出现错误“查询执行期间超出资源:查询无法在分配的内存。峰值使用量:限制的 126%。***内存消费者:ORDER BY 操作:97% 其他/未归因:3%”。 我不想设置限制,因为我需要所有输出行来继续我的分析。临时表和目标表有什么区别。为什么一种有效,一种无效。最后,我该如何解决这个问题?我能想到的唯一方法是减少行数,因此基本上将其分解为多个“相同”查询,以获取最终结果的分区,但这会使我的成本增加约 5-10 倍。
【问题讨论】:
您要对 2000 万行进行排序?为什么? 2000万行排序后下一步是什么?还是只获得前 2000 行就足够了? 每一行代表一个动作,我对它们进行排序(最近的在前),然后将它们交给另一台服务器以按排序顺序进行处理。有一个需要应用于每一行的过程,因此不再发生聚合。我们按此顺序处理它们很重要。有些行没有时间戳(NULL),所以最后我有几百万行时间戳从最新到最旧排序,然后是所有其他行,不确定在排序时如何处理 NULL 行。 关于下一步的好建议。我意识到我将它们分解为不同的动作类型。所以我找到了一个解决方案,我按动作类型分组(我有不到 1000 个),然后在行的其余部分使用带有 ORDER BY 时间戳的 ARRAY_AGG。然后我得到了大量的行(UI 给了我“超出 API 限制:无法返回超过 API 限制的行。要检索行,请导出表”)但我可以使用结果。 将有序结果保存到目标表中没有任何意义和/或任何实际价值 - 因为 BigQuery 中的表根本没有物理顺序的概念。因此,如果您随后将其(无论如何)传递给“另一台服务器进行处理”,则该订单将丢失,并且无论如何您都需要再次订购。如此简单的建议 - 只需在保存结果时删除排序语句 - 并将排序移至进一步处理阶段 【参考方案1】:将 cmets 总结为答案:
您确实不想对 2000 万行进行排序,然后将它们作为表放回 BigQuery。这样做没有什么好处。
您真正想要的是按每种激活类型对行进行排序。一个解决方案是使用ARRAY_AGG()
,以及OVER(PARTITION BY)
。
作为使您的数据为整个表排序的替代方法:使用CLUSTERING BY
。那么您的所有查询将只查询这部分数据。
见:
https://medium.com/google-cloud/bigquery-optimized-cluster-your-tables-65e2f684594b【讨论】:
以上是关于查询在没有目标表的情况下工作,但由于目标表“超出资源”而失败的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用 Join 的情况下处理引用其他表的相关子查询的问题