我有几个表具有无效的Standard-SQL TIMESTAMP
记录。这些记录至少嵌套在数组的一个深层。即使使用旧版SQL,这些记录也会在这些表上中断SELECT *
。他们还以JSON的形式破坏了对表的导出。当我尝试UPDATE
这些表来修复记录时,除非语句同时修复 all 所有,否则UPDATE
会出错。这会导致大UPDATE
个语句。示例:https://gist.github.com/dadrian/b83585c23f6cbbcd5f6d6478c92c745d
UPDATE
语句太大而无法编译!
错误:查询执行期间资源超出:查询计划资源不足 - 太多子查询或查询过于复杂
我接着采用了第二种方法:SELECT
为包含具有无效时间戳的数组(例如STRUCT
字段)的每个父字段输出一个“固定”p443.https.tls
到它自己的方法中表。然后通过加入每个“固定结构”表来UPDATE
原始表。每次SELECT
发生后,UPDATE
看起来像:
UPDATE `scratch.domain_20170819_copy` target
SET
target.p443.https.tls = fixed_https.tls,
target.p443.https_www.tls = fixed_https_www.tls,
target.p25.smtp.starttls.tls = fixed_smtp_starttls.tls
FROM `scratch.domain_20170819_copy` AS original
INNER JOIN `scratch.domain_20170819_https_tls` AS fixed_https
ON original.domain = fixed_https.domain
INNER JOIN `scratch.domain_20170819_https_www_tls` AS fixed_https_www
ON original.domain = fixed_https_www.domain
INNER JOIN `scratch.domain_20170819_smtp_starttls_tls` AS fixed_smtp_starttls
ON original.domain = fixed_smtp_starttls.domain
WHERE
original.domain = target.domain
AND
original.domain = fixed_https.domain
AND
original.domain = fixed_https_www.domain
AND
original.domain = fixed_smtp_starttls.domain
这适用于足够小的表格。在较大的表或具有更多(类似损坏的)字段的表中,UPDATE语句未完成,并且在约30分钟后出现错误
查询执行期间资源超出:ORDER BY运算符使用了太多内存..
如何修复这些表?
编辑:无效的时间戳是由于在数据源中意外输出整数时间戳(毫秒而不是秒)。 BQ解释为秒,这使得时间戳在48000年。
编辑:我将模式和示例数据对象添加到gist。
架构的快速描述:相关数据的格式为a.b.c.tls
,其中tls
是包含所有损坏数据的父对象。 tls
包含许多内容certificate
,它是一个对象,而chain
包含certificate
个对象的数组。 certificate
包含parsed.extensions.signed_certificate_timestamps
,它是结构的数组。 signed_certificate_timestamps
的字段为timestamp
,其中包含有问题的无效时间戳。这实际上意味着每个...tls.certificate.parsed.extensions.signed_certificate_timestamps
都有一个嵌套的无效时间戳,每个...tls.chain.certificate.parsed.....signed_certificate_timestamps
都有一个双重嵌套的无效时间戳。