有没有办法为BigQuery中的查询增加分配的内存?

时间:2019-05-16 09:49:14

标签: google-bigquery

我已经按需要订购了一张大表(约5900万行,7.1 GB),我想查询该表并为该表的每一行获取row_number()。 不幸的是我得到了错误 “查询执行期间超出了资源:无法在分配的内存中执行查询。”

有没有办法增加BigQuery中分配的内存?

这是我的查询,我不知道如何简化它,但是如果您有任何建议,我会接受

SELECT
  row_number() over() as rowNumber,
  game,
  app_version,
  event_date,
  user_pseudo_id,
  event_name,
  event_timestamp,
  country,
  platform
FROM
`mediation_time_BASE`

这是完整的错误消息:

查询执行期间超出了资源:无法在分配的内存中执行查询。高峰使用:限制的146%。内存消耗最大的用户:解析OVER()子句:98%其他/未分配:2%

编辑: 这里的查询代表事件开始和结束的列表,我需要将start事件与其结束链接,因此我遵循以下提示:https://www.interfacett.com/blogs/how-to-use-values-from-previous-or-next-rows-in-a-query-in-sql-server/ 为此,我需要具有row_number()的行,以便将该子查询分成2个(事件以一只手开始,事件以另一只手结束),将它们连接起来,然后每个事件都有一行,其开头和结尾为事件,如下所示(其中子查询代表具有row_number()的查询):

SELECT
   (case when lead(inter.rowNumber) OVER(ORDER BY inter.rowNumber) - inter.rownumber =1
          then lead(inter.rowNumber) OVER(ORDER BY inter.rowNumber)
          else inter.rownumber end) as rowNumber,
    min(inter_success.rowNumber) as rowNumber_success,
    inter.game,
    inter.app_version,
    inter.event_date,
    inter.user_pseudo_id,
    inter.event_timestamp as event_start,
    min(inter_success.event_timestamp) as event_end,
    inter_success.event_name as results
FROM
    (SELECT * FROM `subquery` where event_name = 'interstitial_fetch') as inter INNER JOIN 
    (SELECT * FROM `subquery` where event_name = 'interstitial_fetch_success') as inter_success
            ON inter.rowNumber < inter_success.rowNumber and inter.game= inter_success.game and inter.app_version = inter_success.app_version and inter.user_pseudo_id = inter_success.user_pseudo_id 
GROUP BY inter.rowNumber,inter.game,inter.app_version,inter.event_date,inter.user_pseudo_id,inter.event_timestamp,inter_success.event_name

这对于较小的数据集效果很好,但不适用于5900万行...

3 个答案:

答案 0 :(得分:2)

TL; DR:您不需要增加BigQuery的内存。

为了回答这个问题,您需要了解BigQuery的工作原理。 BigQuery依赖于称为 slots 的执行器计算机。这些插槽的类型都相似,并且内存量有限。

现在,许多操作将数据拆分到多个插槽之间(例如GROUP BY),每个插槽对一部分数据执行约简操作,然后在执行树中向上发送结果。

某些操作必须在单台计算机上执行(例如SORT和OVER),请参见here。 当数据溢出插槽的内存时,您会遇到上述错误。因此,您真正需要的是将插槽类型更改为更高内存的计算机。不幸的是,这是不可能的。您将必须遵循查询最佳实践,以避免对过多数据进行单插槽操作。

可以帮助您的一件事是使用PARTITIONS计算OVER(),因此每个分区将被发送到不同的计算机。 see this example。通常还可以帮忙的另一件事是,如果您还没有这样做,请转到标准SQL。

答案 1 :(得分:1)

  • 要增加项目中的BigQuery插槽,您可能必须联系Google Cloud支持或购买reservations
  • 我假设您对子查询使用了with clause,而子查询又耗尽了内存。我建议的解决方案是创建一个过期表,该表将在几天后自动使用

    语法过期

    OPTIONS(expiration_timestamp = TIMESTAMP_ADD(CURRENT_TIMESTAMP(),间隔5天))

  • 通过这种方法,我想将5900万行查询结果行插入到到期表中将使用更少的插槽。将您的后续子查询替换为到期的表名。

  • 为避免为到期表计费,您可以在执行所有相关查询后将其删除。

答案 2 :(得分:0)

根据官方文档,您需要请求增加预订​​位额...

  

每个项目的最大并发插槽按需定价-2,000

     

按需查询的默认插槽数在所有共享中共享   在单个项目中查询。通常,如果您处理的内容少于   一次100 GB的查询,您不可能全部使用2,000个查询   插槽。

     

要查看您正在使用多少个插槽,请参阅使用以下命令监控BigQuery   堆栈驱动程序。如果您需要超过2000个插槽,请与您的销售人员联系   代表讨论统一费率定价是否满足您的需求。

有关插槽1,请参见此,请求更多内存的过程在这里2