雪花-群集表上的性能不佳

时间:2020-06-12 13:37:29

标签: snowflake-cloud-data-platform

我有一个很大的表(1.5TB,180亿条记录),其中包含IoT类型的数据。通常,它具有EVENT_TYPE(VARCHAR),EVENT_TIME(TIMESTAMP)和一些存储事件数据的列。总共有12种事件类型,记录分布各不相同(从5到10百万到1-5亿)。

大多数查询都针对特定事件类型和日期范围进行过滤。另外,还创建了一些视图,这些视图指向特定事件类型的数据。这些通常是按日期范围查询的。

在CAST(EVENT_TIME AS DATE)的EVENT_TYPE中创建了聚集索引。我认为这将最适合此类工作负载。但是,性能不是很好。

例如,类似SELECT COUNT(1) FROM <event table> WHERE EVENT_TIME >= '2020-01-01' AND EVENT_TYPE = '<some type>'的查询在XL仓库上运行30秒。我希望它的性能更好,因为它使用索引列。另外,它正在扫描25%的分区(174,201个分区中的42,786个),而它仅覆盖总数据的0.5%。

我怀疑聚集索引不是最佳的。 以下是SYSTEM $ CLUSTERING_INFORMATION的初步结果:

{
  "cluster_by_keys" : "LINEAR(EVENT_TYPE, CAST(EVENT_TIME AS DATE))",
  "total_partition_count" : 175792,
  "total_constant_partition_count" : 44575,
  "average_overlaps" : 97273.7777,
  "average_depth" : 93801.4483,
  "partition_depth_histogram" : {
    "00000" : 0,
    "00001" : 44536,
    "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,
    "131072" : 130790,
    "65536" : 466
  }
}

我尝试重新整理表,但是并没有太大改进:

{
  "cluster_by_keys" : "LINEAR(EVENT_TYPE, CAST(EVENT_TIME AS DATE))",
  "total_partition_count" : 173905,
  "total_constant_partition_count" : 55880,
  "average_overlaps" : 78938.3633,
  "average_depth" : 74663.1889,
  "partition_depth_histogram" : {
    "00000" : 0,
    "00001" : 55829,
    "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,
    "04096" : 5,
    "08192" : 7,
    "131072" : 117196,
    "16384" : 15,
    "32768" : 529,
    "65536" : 324
  }
}

查看上面的结果,我发现了两个问题: 1. average_overlaps和average_depth看起来很高 2.直方图偏斜到末尾。我希望分布大致相同

关于什么可能是错误的或如何改进它的任何想法?

谢谢, 里姆维斯

3 个答案:

答案 0 :(得分:0)

关于重叠和深度,这实际上是您想要的。您希望这些数字尽可能接近1。

我为您推荐一些东西:

1)与支持人员联系,了解为什么未启用自动集群

2)使用INSERT WITH OVERWRITE SELECT * FROM table ORDER BY event_time, event_type使用您可以建立的最大仓库来重新创建该表(这样就不会溢出)。最终为您启动自动集群后,这将为您节省金钱。

3)在event_time :: DATE,event_type上创建集群,而不是相反。

我知道文档为这些键指定了另一种方法,但是由于您每天都在该日期之前加载数据,因此自然会按日期对数据进行排序,因此您的自动聚类成本大大降低了保持环境整洁。而且,如果您没有足够的数据来从event_type的附加键中受益,那么无论如何都可以删除它。意思是,如果一天的数据存储量只是少量的数据微型分区,那么无论如何,附加密钥将无济于事。

答案 1 :(得分:0)

TLDR:在定义集群键时尝试使用 hash(event_type) 而不是 event_type 本身。


我遇到了完全相同的问题,我们的 Snowflake 销售工程师告诉我们,这是由 Snowflake 仅使用varchar 字段的前六个字符来确定其集群键的值造成的。< /p>

换句话说,从 Snowflake 的聚类操作的角度来看,以下所有值都将被视为相同:

event_1
event_2
event_3

在我的例子中,聚类显示出与您相似的分布:良好的平均深度、良好的重叠、大部分恒定分区,但分区深度直方图中的尾部非常奇怪。

{
  "cluster_by_keys" : "LINEAR(\n  received_date,\n  event_type\n)",
  "total_partition_count" : 4214,
  "total_constant_partition_count" : 4129,
  "average_overlaps" : 1.0152,
  "average_depth" : 1.7243,
  "partition_depth_histogram" : {
    "00000" : 0,
    "00001" : 4119,
    "00002" : 3,
    "00003" : 4,
    "00004" : 0,
    "00005" : 0,
    "00006" : 0,
    "00007" : 0,
    "00008" : 0,
    "00009" : 0,
    "00010" : 0,
    "00011" : 0,
    "00012" : 0,
    "00013" : 0,
    "00014" : 3,
    "00015" : 0,
    "00016" : 0,
    "00032" : 14,
    "00064" : 71
  }
}

为了解决这个问题,我尝试在 hash(event_type) 上使用聚类键而不是事件类型本身。请注意这如何改进所有指标并修复聚类深度直方图的尾部。

{
  "cluster_by_keys" : "LINEAR(\n  received_date, hash(event_type)\n)",
  "total_partition_count" : 2028,
  "total_constant_partition_count" : 1653,
  "average_overlaps" : 0.357,
  "average_depth" : 1.2002,
  "partition_depth_histogram" : {
    "00000" : 0,
    "00001" : 1643,
    "00002" : 367,
    "00003" : 15,
    "00004" : 3,
    "00005" : 0,
    "00006" : 0,
    "00007" : 0,
    "00008" : 0,
    "00009" : 0,
    "00010" : 0,
    "00011" : 0,
    "00012" : 0,
    "00013" : 0,
    "00014" : 0,
    "00015" : 0,
    "00016" : 0
  }
}

值得注意的是,更好的聚簇表上的分区总数减少了。因此,一些只拉几个分区的查询实际上可能会更慢,因为它们需要加载和扫描更大的分区。

但我的猜测是,对于大多数工作负载,通过在 hash(event) 类型上进行聚类而不是在 event_type 本身上进行聚类,您将获得更好的性能。

答案 2 :(得分:0)

由于您没有使用自动聚类,您应该持续运行 alter table <table_name> recluster; 直到表的 average_depth 低于某个阈值。

对于我们的大表(超过 500 亿行),我们的平均深度阈值为 10。我正在分享我们的一张表的聚类信息,该表与您的相似。

{
  "cluster_by_keys" : "LINEAR(CAST(DWH_TIME AS DATE), N, S)",
  "total_partition_count" : 2035920,
  "total_constant_partition_count" : 0,
  "average_overlaps" : 16.1197,
  "average_depth" : 9.9825,
  "partition_depth_histogram" : {
    "00000" : 0,
    "00001" : 62,
    "00002" : 1521,
    "00003" : 10949,
    "00004" : 29620,
    "00005" : 63038,
    "00006" : 113138,
    "00007" : 169567,
    "00008" : 232884,
    "00009" : 286370,
    "00010" : 304991,
    "00011" : 272397,
    "00012" : 215381,
    "00013" : 149515,
    "00014" : 92013,
    "00015" : 50387,
    "00016" : 22727,
    "00032" : 15506,
    "00064" : 4127,
    "00128" : 1727
  }
}