在 Snowflake 上删除行或重新创建表是否更有效

Fel*_*ffa 1 sql optimization sql-delete snowflake-cloud-data-platform

我有一个包含 600M 行的表,我想删除其中 id 来自另一个表的行的子集。

删除行或重新创建表会更有效吗?

(基于 dbt Slack 上的讨论)

Fel*_*ffa 5

这取决于。有时DELETE更快,有时CREATE OR REPLACE table是最好的选择。

我们必须使用的思维模型是表中的所有数据都存在于多个 Snowflake“微分区”中。如果我DELETE只触及这些微分区之一 - 要么因为我只删除一行,或者因为我要删除的所有行都很好地聚集到一个微分区中 - 那么DELETE更快。

但如果我的DELETE要接触表的多个微分区 - 我宁愿再次重建整个表。

例如,让我们设置 TPC-H-SF100 的克隆:

create or replace table lineitem_100
as
select *
from snowflake_sample_data.tpch_sf100.lineitem
order by l_shipdate
;

select count(*)
from lineitem_100
-- 600,037,902
;

create table lineitem_100b
clone lineitem_100;

create table lineitem_100c
clone lineitem_100;
Run Code Online (Sandbox Code Playgroud)

删除一组随机行需要 25 秒:

use warehouse fh_3xl
;
delete from lineitem_100b
where l_orderkey in (
    select o_orderkey
    from orders_100
    where o_totalprice between 50000 and 120000
)
-- 25s
Run Code Online (Sandbox Code Playgroud)

但是重新创建没有这些行的表需要一半的时间:

insert overwrite into lineitem_100c
select *
from lineitem_100
where l_orderkey not in (
    select o_orderkey
    from orders_100
    where o_totalprice between 50000 and 120000
)
order by l_shipdate
-- 13s
Run Code Online (Sandbox Code Playgroud)

您可以看到,在重新创建表时,我还使用order by.

同样有趣的是,我做了一个insert overwrite替代create or replace table- 这样我们就可以保留我们可以应用于表的所有策略和其他元数据。

删除:

在此输入图像描述

重新创建:

在此输入图像描述

  • 由于我们不知道微分区中的行数,也不知道数据如何分布,因此所有已删除的行可能存在于不同的分区中。因此,如果占整个表的 5-10%,我们可以删除,否则重新创建是更好的选择。像@Felipe 那样的快速研发是最好的。 (2认同)
  • 此外,如果您启用了集群,则创建成本会更低。因为删除会写入未排序的分区,然后集群将重写所有分区。因此,与删除和自动聚类相比,使用排序创建(通过聚类键)将具有总成本和一般时间来更快地完成。 (2认同)