集群如何帮助 Snowflake 中的查询修剪?

How clustering is helping in query pruning in Snowflake?

我有一个 table 集群在 s_nation_key 上,如下所示。

create or replace table t1 
( S_SUPPKEY string,
  S_NAME string,
  S_NATIONKEY string,
  S_ADDRESS string,
  S_ACCTBAL string) cluster by (S_NATIONKEY);

现在我已经添加了数据

INSERT INTO  T1
SELECT S_SUPPKEY , S_NAME,S_NATIONKEY,S_ADDRESS,S_ACCTBAL
  FROM "SNOWFLAKE_SAMPLE_DATA"."TPCH_SF1000"."SUPPLIER"
 WHERE S_NATIONKEY=7
limit 50000;

当我检查底层微分区中的数据分布时,它看起来不错。

>select system$clustering_information('t1','S_NATIONKEY'); 
{   "cluster_by_keys" : "LINEAR(S_NATIONKEY)",   "total_partition_count" : 1,   "total_constant_partition_count" : 0,   "average_overlaps" : 0.0, "average_depth" : 1.0,   "partition_depth_histogram" : {
        "00000" : 0,
        "00001" : 1,
        "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   } }

我再次为特定的 s_nation_key 设置加载了更多记录,如下所示。

--batch load 2
INSERT INTO  T1
SELECT S_SUPPKEY , S_NAME,S_NATIONKEY,S_ADDRESS,S_ACCTBAL
  FROM "SNOWFLAKE_SAMPLE_DATA"."TPCH_SF1000"."SUPPLIER"
 WHERE S_NATIONKEY=3
 LIMIT 50000;

--batch load 3
INSERT INTO  T1
SELECT S_SUPPKEY , S_NAME,S_NATIONKEY,S_ADDRESS,S_ACCTBAL
  FROM "SNOWFLAKE_SAMPLE_DATA"."TPCH_SF1000"."SUPPLIER"
 WHERE S_NATIONKEY=1
limit 50000;

--batch load 3
INSERT INTO  T1
SELECT S_SUPPKEY , S_NAME,S_NATIONKEY,S_ADDRESS,S_ACCTBAL
  FROM "SNOWFLAKE_SAMPLE_DATA"."TPCH_SF1000"."SUPPLIER"
 WHERE S_NATIONKEY=2
 and   S_ACCTBAL>0
limit 50000;

现在,当我再次检查聚类信息时,这看起来也不错。现在共有 4 个微分区,每个不同的 S_NATIONKEY 值集被加载到单独的分区中,在 range.So 中没有重叠,所有微分区的聚类深度为 1。

>select system$clustering_information('t1','S_NATIONKEY');
{
  "cluster_by_keys" : "LINEAR(S_NATIONKEY)",
  "total_partition_count" : 4,
  "total_constant_partition_count" : 4,
  "average_overlaps" : 0.0,
  "average_depth" : 1.0,
  "partition_depth_histogram" : {
    "00000" : 0,
    "00001" : 4,
    "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
  }
}

现在根据 Snowflake 文档和查询修剪的概念,每当我们搜索属于一个 cluster_key 值的记录时,它应该只扫描特定的微分区,该微分区将持有 cluster_key值(基于每个微分区的 min/max 值范围)。但就我而言,它正在扫描所有底层微分区(如下所示)

。 根据上面的查询计划统计,它正在扫描所有分区,而不是扫描 1

我在这里遗漏了什么吗?它背后的逻辑是什么?? 请帮助我理解 Snowflake 中的这种情况。

谢谢, @Himanshu

Autoclustering 或集群键并非适用于所有 table。通常建议使用大小达到 Terra 字节的非常大的 table。我们不应该将簇键与大多数 RDBMS 系统中可用的任何索引类型的对象进行比较。在这里,我们以有序的方式将数据分组到微分区中,这有助于避免扫描可能不包含请求数据的分区。在小 tables 的情况下,如果引擎估计这不是一个昂贵的操作,它更愿意扫描所有分区。

参考文档的注意部分:

https://docs.snowflake.com/en/user-guide/tables-clustering-keys.html#clustering-keys-clustered-tables.

这里 table 的大小不是那么大,这就是为什么它扫描所有分区而不是一个分区。即使您检查扫描的总大小,它也只有 7.96 mb,这很小,因此 SF 扫描所有分区