集群如何帮助 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 的情况下,如果引擎估计这不是一个昂贵的操作,它更愿意扫描所有分区。
参考文档的注意部分:
这里 table 的大小不是那么大,这就是为什么它扫描所有分区而不是一个分区。即使您检查扫描的总大小,它也只有 7.96 mb,这很小,因此 SF 扫描所有分区
我有一个 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 的情况下,如果引擎估计这不是一个昂贵的操作,它更愿意扫描所有分区。
参考文档的注意部分:
这里 table 的大小不是那么大,这就是为什么它扫描所有分区而不是一个分区。即使您检查扫描的总大小,它也只有 7.96 mb,这很小,因此 SF 扫描所有分区