【发布时间】:2021-09-13 21:53:44
【问题描述】:
我有一个从 OLTP 数据库流向 BQ 的数据。因此,如果任何行被更新,BQ 会在 2 个不同的行中同时包含新旧记录。所以我有一个查询去重复数据,但我想每天至少一次从 BQ 中删除旧值。
这是我的选择查询,它将为我提供最新记录。
SELECT DISTINCT o._sdc_sequence
FROM `my-production.bqtest.mytbl` o
INNER JOIN (
SELECT id,
MAX(_sdc_sequence) AS seq,
MAX(_sdc_batched_at) AS batch
FROM `my-production.bqtest.mytbl`
GROUP BY id) oo
ON o.id = oo.id
AND o._sdc_sequence = oo.seq
AND o._sdc_batched_at = oo.batch
-
id- 整数(主键) -
sdc_sequence- unix时间戳(数据插入BQ时) -
_sdc_batched_attimestamp - (它是一个批处理,所以是批处理开始时间的时间戳)
以上列的样本数据:
select id,
_sdc_sequence,
_sdc_batched_at
FROM `my-production.bqtest.mytbl`
ID: 2741332
_sdc_sequence: 1565726907840002084
_sdc_batched_at: 2019-08-13 21:01:07.687 UTC
我想删除旧记录,我可以用最新的行进行每日表轮换,但是如果我更改表结构上的某些内容,我使用的 ETL 工具将不起作用。
我在下面的查询中尝试了这个,但它也删除了一些有效的行。
delete from `my-production.bqtest.mytbl` where _sdc_sequence not in(
SELECT DISTINCT o._sdc_sequence
FROM `my-production.bqtest.mytbl` o
INNER JOIN (
SELECT id,
MAX(_sdc_sequence) AS seq,
MAX(_sdc_batched_at) AS batch
FROM `my-production.bqtest.mytbl`
GROUP BY id) oo
ON o.id = oo.id
AND o._sdc_sequence = oo.seq
AND o._sdc_batched_at = oo.batch
因为我有2行具有相同的序列ID,所以我需要用where _sdc_sequence not in + max(_sdc_batched_at)过滤掉它
或任何其他更好的查询来执行此操作。
【问题讨论】:
-
Google Bigquery 等平台在硬删除方面并不是很好的性能解决方案。您是否考虑过软删除解决方案,即在大查询中汇总所有版本的增量提要并创建使用分区函数(例如行号)来抑制所有非最新版本的行的特定视图?
-
是的,即使我不乐意这样做,但是,它的要求,我需要实现。这就是为什么我每天都这样做一次。然后它将减少我的查询执行时间。
-
使用删除来改变目标 BQ 表的要求也意味着每次运行硬删除时都会丢失所有非最近记录的历史记录,使用物化视图,您可以获取在目标 BQ 表上完成的所有流插入的完整数据沿袭。
标签: sql google-cloud-platform google-bigquery