【问题标题】:Snowflake joins performance improvement雪花加入性能改进
【发布时间】:2021-08-01 15:19:36
【问题描述】:

我需要在包含 1300 多列的表上创建一个视图。每个季度都会将新数据加载到表中(以百万为单位的行)。在创建视图时,我需要将其他表与基表连接起来。而且我还需要在视图中添加一个最近的行指示器。

CREATE OR REPLACE SECURE VIEW VIEW_NAME AS
SELECT lkp_tbl.col1,base_tbl.col1,base_tbl.col2,base_tbl.col3,........,base_tbl.col1334,1 as Is_Latest_Quarter FROM base_tbl full outer JOIN lkp_tbl
on base_tbl.CUST_ID = lkp_tbl.CUST_ID 
where snapshot_dt=(select max(snapshot_dt) from base_tbl)


union all


SELECT lkp_tbl.col1,base_tbl.col1,base_tbl.col2,base_tbl.col3,........,base_tbl.col1334,0 as Is_Latest_Quarter FROM base_tbl full outer JOIN lkp_tbl
on base_tbl.CUST_ID = lkp_tbl.CUST_ID 
where snapshot_dt!=(select max(snapshot_dt) from base_tbl);

创建此视图后,即使我们查询 100 行,查询的性能也太慢了。有没有一种方法可以让我们以更有效的方式创建视图。如果不是,我该如何提高性能?

【问题讨论】:

  • 你的基表是否被任何东西聚集在一起?可能想看看您对 snapshot_dt 的修剪是否有好处,并可能尝试对它进行聚类。另外,如果视图不安全,性能有何不同?
  • @MikeWalton 是的,该表聚集在 run_id 上。对于同一快照日期,我们可能有多个 run_id。
  • 但这似乎与您最初编写的查询完全不同?表名不同,列名不同,还涉及到额外的列...
  • 对不起@NickW 我刚刚创建了一个遵循我原始查询结构的查询。我已更新示例查询以遵循旧表名。 CREATE OR REPLACE SECURE VIEW VIEW_NAME AS select lkp_tbl.col1,base_tbl.* from lkp_tbl right join (SELECT t.col1,t.col2,t.col3,t.col4,t.col5,...........,t.col1334, case when snapshot_dt!=(select max(snapshot_dt) from base_tbl) then 0 else 1 end as current_row_ind FROM base_tbl_name t) base_tbl on base_tbl.ALT_CUST_ID = lkp_tbl.ALT_CUST_ID;
  • 没有问题。无论如何,我已经用几个 SQL 选项更新了我之前的答案,这些选项应该可以帮助你实现你想要的

标签: join snowflake-cloud-data-platform sql-view


【解决方案1】:

只需使用一个 SELECT 语句并使用 CASE 语句计算 Is_Latest_Quarter

使用(几乎)实际 SQL 更新

CREATE OR REPLACE SECURE VIEW VIEW_NAME AS
SELECT {list of columns you want to include}
,CASE WHEN snapshot_dt=(select max(snapshot_dt) from base_tbl) THEN 1 
 ELSE 0 END as Is_Latest_Quarter
FROM base_tbl 
full outer JOIN lkp_tbl on base_tbl.CUST_ID = lkp_tbl.CUST_ID 

或者,如果 Snowflake 不喜欢该内联子查询,您可以使用类似以下的 CTE:

CREATE OR REPLACE SECURE VIEW VIEW_NAME AS
    WITH MAX_DATE AS (SELECT MAX(Ssnapshot_dt) AS max_snapshot_dt FROM base_tbl),
    SELECT {list of columns you want to include}
    ,CASE WHEN max_date.max_snapshot_dt is not null  THEN 1 
     ELSE 0 END as Is_Latest_Quarter
    FROM base_tbl 
    full outer JOIN lkp_tbl on base_tbl.CUST_ID = lkp_tbl.CUST_ID
    LEFT OUTER JOIN MAX_DATE ON base_tbl.snapshot_dt = max_date.max_snapshot_dt

【讨论】:

  • 我已将创建视图语句修改为create or replace view view_name as select ref.Profile_KEY,base.* from reference_table_name ref right join (SELECT t.col1,t.col2,t.col3,t.col4,t.col5,...........,t.col1330,t.snapshot_dt,t.RUN_ID, case when snapshot_dt!=(select max(snapshot_dt) from base_table_name) then 0 else 1 end as current_row_ind FROM base_table_name t) base on base.ALT_CUST_ID = ref.ALT_CUST_ID; 我可以进一步改进我的 SQL 语句吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-29
相关资源
最近更新 更多