雪花分区与手动集群

Posted

技术标签:

【中文标题】雪花分区与手动集群【英文标题】:Snowflake Partitioning Vs Manual Clustering 【发布时间】:2021-08-30 19:02:08 【问题描述】:

我在 Snowflake 中有 2 个存储点击事件的大表(分别为 ~1 和 ~15 TB)。它们存在于两种不同的模式中,但具有相同的列和结构;只是来源不同。

数据每月转储/附加到这些表中,并且两个表都有一个 time_id 整数字段,表示自发生点击事件以来的天数。

问题 -- 我是否应该让 Snowflake 来优化分区 --OR-- 这是否适合手动分配集群键?并且说,我确实决定向它添加一个集群键,下次插入后重新集群是否只是为了增量数据? --OR-- 会不会和初始集群一样昂贵?

如果有帮助,这里是两张表中较大的一张的一些聚类信息

select system$clustering_information( 'table_name', '(time_id)')


  "cluster_by_keys" : "LINEAR(time_id)",
  "total_partition_count" : 1151026,
  "total_constant_partition_count" : 130556,
  "average_overlaps" : 4850.673,
  "average_depth" : 3003.3745,
  "partition_depth_histogram" : 
    "00000" : 0,
    "00001" : 127148,
    "00002" : 0,
    "00003" : 0,
    "00004" : 0,
    "00005" : 0,
    "00006" : 0,
    "00007" : 0,
    "00008" : 0,
    "00009" : 0,
    "00010" : 0,
    "00011" : 0,
    "00012" : 0,
    "00013" : 0,
    "00014" : 0,
    "00015" : 0,
    "00016" : 0,
    "01024" : 984,
    "02048" : 234531,
    "04096" : 422451,
    "08192" : 365912
  

我将针对这些表运行的典型查询

select col1, col_2, col3, col4, time_id
from big_table 
where time_id between 6000 and 7600;

【问题讨论】:

您对这些数据运行了哪些查询?如果你选择它,你会选择什么集群策略?您是否有任何特定的查询要提高性能? @FelipeHoffa 我想我可以利用基于时间的集群键来更容易地将所需的数据子集转储到临时表中,然后对我想象的那个临时表进行所有繁重的工作小得多。我还可以按 time_id 和 domain 进行聚类,因为 domain 是一种流行的 where 子句条件,但我不确定这是否会产生重大开销。这些表不经常被查询,但是当他们查询时,性能真的很差 【参考方案1】:

我应该让 Snowflake 来优化分区吗?是 这是手动分配聚类键的理想选择吗?

是的,分配聚类键似乎是一个不错的选择(大小 + 更新间隔 + 查询过滤器)

并且说,我确实决定向它添加一个集群键,会 下次插入后重新聚类只是为了增量数据吗?

在初始重新集群后,如果您不插入属于较早日期的数据,现有分区将处于“恒定”状态,因此重新集群将仅处理新数据/微分区。

https://docs.snowflake.com/en/user-guide/tables-auto-reclustering.html#optimal-efficiency

它会和初始集群一样昂贵吗?

在正常情况下,它不应该。

【讨论】:

这很有帮助!只是让我对成本和时间有所了解,您认为运行集群需要多长时间?【参考方案2】:

对 Gokhan 回答的问题主要是冗长的赞扬:

这很有帮助!顺便说一下,我对成本和时间有所了解,您认为运行集群需要多长时间?

我建议您使用 order by time 诗句离开自动集群来对这么大的表进行增量排序。

我这么说是因为我们有一组表,每个表大约有 3B 行(这些表大约有 30 倍),并且每个月都会进行 GDPR 相关的 PII 清理,通过 UPDATE 命令删除 1 个月的数据,因为 UPDATE 没有订单,订单被销毁了大约 1/3 的表,然后自动集群将在第二天“修复”。

我们的自动集群账单是正常的,每天约 100 积分,但这些天我们使用约 300 积分。这意味着每张表约 6 个学分,其中使用 order by 重新创建完整表可能需要 15 分钟,所以约 1 个学分。

这并不是在嘲笑自动集群,但是当一个表被随机打乱时,“一次一点”的方法太被动/昂贵,恕我直言。

但另一方面,当您重新创建表时,您不能在 N 分钟内阻止插入过程,也许自动集群可能是您唯一的选择,另一方面,如果您总是自动写入表-cluster 会因写入失败而后退很多。但这一点更像是“需要注意的一般案例细节”,正如您所说的每月负载一样。

【讨论】:

您是否建议order by time_id 在创建表期间强制/提示 Snowflake 更有效地对其进行分区? 如果您执行CREATE TABLE <with the replace option> AS SELECT from old table ORDER BY time_id 并且 time_id 是您的集群 ID,那么是的,您将拥有完美的集群。 今天我还在和一位 Snowflake 性能工程师交谈,更新集群表会破坏所有解决方案。因此,一旦正式发布,那将是一件很棒的事情。

以上是关于雪花分区与手动集群的主要内容,如果未能解决你的问题,请参考以下文章

在雪花中设置表自动聚类不会对表进行聚类

使用分区的雪花到 Hive 数据移动

是否可以选择在雪花表上强制分区

如何使用主键和分区列创建雪花表?示例 DDL?

雪花 - Azure 文件上传 - 如果文件大小超过 40MB,我如何对文件进行分区

在雪花中按分区过滤