我在大表上遇到了合并语句的问题。 合并的源表基本上是应用一些 DML 后目标表的克隆。
例如在下面的示例中,PUBLIC.customer 是目标,STAGING.customer 是源。
CREATE OR REPLACE TABLE STAGING.customer CLONE PUBLIC.customer;
MERGE INTO STAGING.customer TARGET USING (SELECT * FROM NEW_CUSTOMER) AS SOURCE ON TARGET.ID = SOURCE.ID
WHEN MATCHED AND SOURCE.DELETEFLAG=TRUE THEN DELETE
WHEN MATCHED AND TARGET.ROWMODIFIED < SOURCE.ROWMODIFIED THEN UPDATE SET TARGET.AGE = SOURCE.AGE, ...
WHEN NOT MATCHED THEN INSERT (AGE) VALUES (AGE, DELETEFLAG, ID,...);
目前,我们只是在最后将 STAGING.customer 合并回 PUBLIC.customer。 对于一些大表来说,这个最终的合并语句是非常昂贵的。
在寻找降低成本的解决方案时,我发现了雪花“CHANGES”机制。根据文档,
目前,在为表记录更改跟踪元数据之前,必须至少满足以下一项:
这两个选项都将隐藏列添加到存储更改跟踪元数据的表中。这些列占用少量存储空间。
我假设添加到表中的元数据等同于使用“changes”子句的 select 语句的结果集,但似乎并非如此。
INSERT INTO PUBLIC.CUSTOMER(AGE,...) (SELECT AGE,... FROM STAGING.CUSTOMER CHANGES (information => default) at(timestamp => 1675772176::timestamp) where "METADATA$ACTION" = 'INSERT' );
使用“changes”子句的 select 语句比我目前使用的 merge 语句慢得多。
我检查了执行计划,发现 Snowflake 在两个不同的时间戳上对表执行了自连接(某种)。
真的应该是行为还是我在这里遗漏了什么?我希望获得更好的性能假设扫描一次表然后简单地插入应该比合并语句更快的新记录。
另外,即使它做了自连接,为什么合并查询的性能比这个好,合并查询也在类似的卷上做连接。
我也希望使用相同的机制来删除/更新源表。
正在做与此非常相似的事情。合并似乎工作正常,但也需要太长时间。想知道编写 python UDF 并在任何目标表上调用它是否会更快。在这里大声思考,仍然不知道该怎么做。