当前,我正在使用Google Storage
将数据从stage_table_orders
加载到WRITE_APPEND
。由于此订单同时加载新订单和现有订单,因此可能会出现同一订单具有多个版本的情况,字段etl_timestamp
会告诉哪一行是最新的。
然后我用类似的查询WRITE_TRUNCATE
production_table_orders
select ...
from (
SELECT * , ROW_NUMBER() OVER
(PARTITION BY date_purchased, orderid order by etl_timestamp DESC) as rn
FROM `warehouse.stage_table_orders` )
where rn=1
然后production_table_orders
始终包含每个订单的最新版本。
此过程假设每3分钟运行一次 。
我想知道这是否是最佳实践。
我大约有2000万行。每3分钟WRITE_TRUNCATE
行2000万行似乎并不明智。
建议?
答案 0 :(得分:2)
我们正在做同样的事情。但是,为了帮助提高性能,请尝试按date_purchased
对表进行分区,并按orderid
进行集群。
使用CTAS语句(对表本身),因为事后您无法添加分区。
编辑:使用2个表并合并
取决于您的特定用例,即可以在新旧之间更新的字段数,您可以使用2个表,例如stage_table_orders
用于导入记录,final_table_orders
作为目标表并执行
像这样的MERGE
:
MERGE final_table_orders F
USING stage_table_orders S
ON F.orderid = S.orderid AND
F.date_purchased = S.date_purchased
WHEN MATCHED THEN
UPDATE SET field_that_change = S.field_that_change
WHEN NOT MATCHED THEN
INSERT (field1, field2, ...) VALUES(S.field1, S.field2, ...)
专业版:如果“行插入”的行很少,而不是数百万(尽管未经测试)+修剪分区应该有效,则非常有效。
缺点:您必须在update和insert子句中明确列出字段。如果架构几乎是固定的,则只需一次即可。
有多种方法可以进行重复数据删除,并且没有一刀切的功能。使用ARRAY_AGG
或EXISTS
或DELETE
的{{1}}在SO中搜索类似的请求,...尝试一下,看看哪个对您的数据集效果更好。