【问题标题】:LISTAGG Func Performance in Snowflake雪花中的 LISTAGG Func 性能
【发布时间】:2021-05-23 12:52:44
【问题描述】:

在 Snowflake 中运行以下 SQL,

select I_CLASS_ID,LISTAGG(I_CLASS,',') OVER(PARTITION BY I_CLASS_ID) 
FROM "SNOWFLAKE_SAMPLE_DATA"."TPCDS_SF100TCL"."ITEM" 
WHERE I_CLASS_ID IS NOT NULL

使用 XSmall Warehouse 运行 SQL。

查询耗时 40 多分钟,但仍在运行,不得不中止。该表非常小,因此试图了解为什么要花这么长时间。该配置文件指出,4 个节点中有 1 个在完成大部分工作。有什么原因吗?

select LISTAGG(I_CLASS,',') OVER(PARTITION BY I_CLASS_ID) 
FROM "SNOWFLAKE_SAMPLE_DATA"."TPCDS_SF100TCL"."ITEM" 
WHERE I_CLASS_ID IS NOT NULL

上面一个是瞬间跑过去的。

【问题讨论】:

    标签: snowflake-cloud-data-platform


    【解决方案1】:

    第一个,对每一行进行聚合,所以如果你有 100 万行,你将得到 100 万行,包含所有的 id。

    第二个 while 应该给出相同的结果,优化器可能会告诉它可以运行 SQL:

    SELECT A.I_CLASS_ID
        B.LIST
    FROM FROM "SNOWFLAKE_SAMPLE_DATA"."TPCDS_SF100TCL"."ITEM" AS A
    JOIN (
        SELECT I_CLASS_ID, 
            LISTAGG(I_CLASS,',') AS list
        FROM "SNOWFLAKE_SAMPLE_DATA"."TPCDS_SF100TCL"."ITEM" 
        WHERE I_CLASS_ID IS NOT NULL
        GROUP BY 1
    ) AS B
        ON A.I_CLASS_ID = B.I_CLASS_ID;
    

    将返回 100 万行,但速度非常快。

    我怀疑你真正想要的只是内部。

    【讨论】:

      【解决方案2】:

      您没有说#2 的查询计划是什么,但我怀疑它是“即时”运行的。 它尝试了您的两个查询并在 2 多分钟后将其杀死。 然后我跑了: 选择 I_CLASS_ID,LISTAGG(I_CLASS,',') OVER(PARTITION BY I_CLASS_ID) FROM "SNOWFLAKE_SAMPLE_DATA"."TPCDS_SF100TCL"."ITEM" 其中 I_CLASS_ID 为空; 运行时间不到 1 秒。

      然后我跑了:

      select i_class_id,avg(length(i_class)),max(length(i_class)) from item group by 1;
      

      接着是:

      select i_class_id,count(i_class)*8 from item where i_class_id is not null group by 1;
      

      您正在创建非常大的 listagg,大小从 125 KB 到 625 KB。 建议您尝试更大的 DW 尺寸。另外,请确保您长时间运行的查询不是由于排队。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-12-15
        • 1970-01-01
        • 1970-01-01
        • 2020-05-22
        • 2021-08-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多