【问题标题】:Resources exceeded during query execution BigQuery when using LAST_VALUE() OVER()使用 LAST_VALUE() OVER() 时查询执行 BigQuery 期间超出资源
【发布时间】:2021-03-11 09:44:53
【问题描述】:

我有一个相当长的表,大小为 2.47GB,有 1.126 亿行。该表有 8 列,第一列是 TIMESTAMP 类型,另外 7 列是 FLOAT 类型。该表已分区(天)并由datetime 聚集。

表格如下所示:

datetime                    col1     col2     col3    col4    col5    col6     col7
2020-07-29 07:19:24.920 UTC null     null     null    null    null    null     0.01 
2020-07-29 16:41:53.094 UTC 1.3344   null     null    0.6975  null    null     0.01 
2020-07-29 08:05:23.705 UTC null     1.698    null    null    null    null     0.01 
2020-07-29 18:12:21.396 UTC 1.33435  null     null    null    null    null     0.01 
2020-07-29 19:49:26.073 UTC null     1.12345  null    null 1.33435    null     0.01 
2020-07-29 19:33:21.540 UTC null     null     null    null 1.33377    null     0.01
2020-07-29 04:11:24.596 UTC 1.256    null     null    null 1.33694    null     0.01     
2020-07-29 09:27:05.052 UTC null     null     null    0.6868  null    104.889  0.01

我要做的是用与该表相同的值填充其他表,但执行 null 值的前向填充,我正在阅读可以使用 LAST_VALUE 函数实现的文档。

我尝试执行的查询使用LAST_VALUEOVER 用于除最后一列之外的所有列。

INSERT project.dataset.table (datetime, col1,col2,col3,col4,col5,col6)

WITH current AS(
SELECT
datetime,
   LAST_VALUE(col1 IGNORE NULLS) OVER (ORDER BY datetime) AS col1,
   
   LAST_VALUE(col2 IGNORE NULLS) OVER (ORDER BY datetime) AS col2,
   
   LAST_VALUE(col3 IGNORE NULLS) OVER (ORDER BY datetime) AS col3,
   
   LAST_VALUE(col4 IGNORE NULLS) OVER (ORDER BY datetime) AS col4,
   
   LAST_VALUE(col5 IGNORE NULLS) OVER (ORDER BY datetime) AS col5,
   
   LAST_VALUE(col6 IGNORE NULLS) OVER (ORDER BY datetime) AS col6,
   
FROM
  project.dataset.origin_table

ORDER BY
  datetime)
  select * from current

但是,运行此查询会返回此错误:

Resources exceeded during query execution: The query could not be executed in the allotted memory. Peak usage: 100% of limit. Top memory consumer(s): sort operations used for analytic OVER() clauses: 97% other/unattributed: 3%

因此,对于阅读错误消息,很明显OVER 是问题所在,除非我遗漏了某些内容或我不理解某些内容。

我怎样才能做到这一点?期望的输出是这样的:

datetime                    col1     col2     col3    col4      col5    col6     col7
2020-07-29 07:19:24.920 UTC null     null     null    null      null    null     0.01   
2020-07-29 16:41:53.094 UTC 1.3344   null     null    0.6975    null    null     0.01   
2020-07-29 08:05:23.705 UTC 1.3344   1.698    null    0.6975    null    null     0.01   
2020-07-29 18:12:21.396 UTC 1.33435  1.698    null    0.6975    null    null     0.01   
2020-07-29 19:49:26.073 UTC 1.33435  1.12345  null    0.6975   1.33435  null     0.01   
2020-07-29 19:33:21.540 UTC 1.33435  1.12345  null    0.6975   1.33377  null     0.01
2020-07-29 04:11:24.596 UTC 1.256    1.12345  null    0.6975   1.33694  null     0.01   
2020-07-29 09:27:05.052 UTC 1.256    1.12345  null    0.6868   1.33694  104.889  0.01

用每列中遇到的最后一个值填充空值。

谢谢!

【问题讨论】:

    标签: sql google-cloud-platform google-bigquery


    【解决方案1】:

    问题不在于LAST_VALUE()。问题是窗口规范中缺少PARTITION BY。您可以通过一个小技巧来验证这一点,即引入日期作为分区元素。

    那么,这行得通吗?

    LAST_VALUE (col1 IGNORE NULLS) OVER (PARTITION BY DATETIME_TRUNC(datetime, day) ORDER BY datetime) AS col1,
    

    我并不是说这会返回你想要的结果,但它应该解决资源超出问题。

    然后。 . .如果可能是您有一个应该使用的自然PARTITION BY。如果是这样,请使用它。如果没有,可能还有其他方法可以获得您想要的结果。

    【讨论】:

    • 嗨@Gordon Linoff,好久不见:)。是的,我尝试过使用分区列,但没有得到我真正需要的结果。也许我以错误的方式使用分区?我也对其他选项持开放态度,比如数据流?
    • @PedroPabloSeverinHonorato 。 . .但查询以 partition by? 完成。是否有任何其他自然列可用于分区?另外,NULL 值有多常见?
    • 只有当我使用 OVER 时,它才会完成分区,但如果我添加 1 个额外的列,它会失败。无论如何,使用该分区使表几乎与我没有运行查询一样:(
    【解决方案2】:

    您看到的错误消息是指您的 OVER 子句的排序部分,即“ORDER BY”。

    使用分析函数时,每个最终分区中的所有数据都需要由同一个工作人员处理。当要处理的数据量(在这种情况下是排序的)非常高时,有时它可以分配到内存中并失败。目前在这些情况下没有增加内存的选项,只有变通方法。

    尝试在第一阶段仅使用一列,然后将所有列粘贴到一个表中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多