首页 > 解决方案 > 连接的性能问题

问题描述

我加入了两张表现不佳的桌子。

表格1 :

时期 国家 公司 产品
2020 年 1 月 1 日 欧洲、中东和非洲 WKDM2 产品1
2020 年 1 月 2 日 欧洲、中东和非洲 PRL56 产品1
2020 年 1 月 3 日 欧洲、中东和非洲 英国 ORD56 产品2
2020 年 1 月 4 日 欧洲、中东和非洲 GFDS 产品3
2020 年 1 月 5 日 欧洲、中东和非洲 FR 24GFDSGF2 产品1
2020 年 1 月 6 日 欧洲、中东和非洲 2GFSDG37 产品3
2020 年 1 月 7 日 欧洲、中东和非洲 2GFDSG35 产品1
2020 年 1 月 8 日 欧洲、中东和非洲 23GSFDG6 产品4
2020 年 1 月 9 日 欧洲、中东和非洲 23GSFDG5 产品6
2020 年 1 月 10 日 欧洲、中东和非洲 24GSFD1 产品1
2020 年 1 月 11 日 欧洲、中东和非洲 23GSDF6 产品3
2020 年 1 月 12 日 欧洲、中东和非洲 FI 24GFSDG1 产品8

表2:

时期 国家 四分之一 公司 产品
2020 年 1 月 1 日 欧洲、中东和非洲 2020 年 1 月 1 日 2020 年 1 月 1 日 WKDM2 产品1
2020 年 1 月 2 日 欧洲、中东和非洲 2020 年 1 月 1 日 2020 年 1 月 1 日 PRL56 产品1
2020 年 1 月 3 日 欧洲、中东和非洲 英国 2020 年 1 月 1 日 2020 年 1 月 1 日 ORD56 产品2
2020 年 1 月 4 日 欧洲、中东和非洲 2020 年 1 月 4 日 2020 年 1 月 1 日 GFDS 产品3
2020 年 1 月 5 日 欧洲、中东和非洲 FR 2020 年 1 月 4 日 2020 年 1 月 1 日 24GFDSGF2 产品1
2020 年 1 月 6 日 欧洲、中东和非洲 2020 年 1 月 4 日 2020 年 1 月 1 日 2GFSDG37 产品3
2020 年 1 月 7 日 欧洲、中东和非洲 2020 年 1 月 7 日 2020 年 1 月 1 日 2GFDSG35 产品1
2020 年 1 月 8 日 欧洲、中东和非洲 2020 年 1 月 7 日 2020 年 1 月 1 日 23GSFDG6 产品4
2020 年 1 月 9 日 欧洲、中东和非洲 2020 年 1 月 7 日 2020 年 1 月 1 日 23GSFDG5 产品6
2020 年 1 月 10 日 欧洲、中东和非洲 2020 年 1 月 10 日 2020 年 1 月 1 日 24GSFD1 产品1
2020 年 1 月 11 日 欧洲、中东和非洲 2020 年 1 月 10 日 2020 年 1 月 1 日 23GSDF6 产品3
2020 年 1 月 12 日 欧洲、中东和非洲 FI 2020 年 1 月 10 日 2020 年 1 月 1 日 24GFSDG1 产品8

在我的示例中,数据是相同的,但在 Production ENV 中,表 1 中的公司是事实来源。第二张桌子上的产品是事实的来源。

Table1 有 6M 行,table2 有 600K 行。

当我这样加入时,我的表现很差,我该如何改善呢?

SELECT R."Period",R."Zone",R."Country",S."Quarter",S."Year",R."Company",S."Product"
FROM table1 AS R,
    table2 AS S 
WHERE R."Period" = S."Period"
AND R."Zone" = S."Zone"
AND R."Country"=S."Country"
 GROUP BY 1,2,3,4,5,6,7

更新:

测试数据集:

CREATE OR REPLACE TEMPORARY TABLE "TMP_TEST1" (
    "Period"  TIMESTAMP,
    "Country"     VARCHAR,
    "Quarter"    TIMESTAMP,
    "Year"    TIMESTAMP,
    "Company"    VARCHAR,
    "Product"    VARCHAR
);

INSERT INTO "TMP_TEST1" 
VALUES 
('01/01/2020','DE','01/01/2020    ','01/01/2020   ','WKDM2    ','Product1'),
('01/01/2020','DE','01/01/2020    ','01/01/2020   ','2GFSDG37  ','Product1'),
('01/02/2020','DE','01/01/2020    ','01/01/2020   ','ORD56    ','Product2'),
('01/03/2020','DE','01/01/2020    ','01/01/2020   ','GFDS     ','Product3'),
('01/03/2020','DE','01/01/2020    ','01/01/2020   ','24GFDSGF2 ','Product1'),
('01/03/2020','DE','01/01/2020    ','01/01/2020   ','24GSFD1   ','Product1'),
('01/04/2020','DE','01/04/2020    ','01/01/2020   ','2GFSDG37  ','Product4'),
('01/04/2020','DE','01/04/2020     ','01/01/2020      ','23GSFDG5  ','Product6'),
('01/05/2020','DE','01/04/2020    ','01/01/2020   ','23GSDF6   ','Product3'),
('01/06/2020','DE','01/04/2020    ','01/01/2020   ','24GSFD1   ','Product8');

CREATE OR REPLACE TEMPORARY TABLE "TMP_TEST2" (
    "Period"  TIMESTAMP,
    "Country"     VARCHAR,
    "Quarter"    TIMESTAMP,
    "Year"    TIMESTAMP,
    "Company"    VARCHAR,
    "Product"    VARCHAR
);

INSERT INTO "TMP_TEST2" 
VALUES 
('01/01/2020','DE','01/01/2020    ','01/01/2020   ','WKDM2    ','Product1'),
('01/01/2020','DE','01/01/2020    ','01/01/2020   ','2GFSDG37  ','Product1'),
('01/02/2020','DE','01/01/2020    ','01/01/2020   ','ORD56    ','Product2'),
('01/03/2020','DE','01/01/2020    ','01/01/2020   ','GFDS     ','Product3'),
('01/03/2020','DE','01/01/2020    ','01/01/2020   ','24GFDSGF2 ','Product1'),
('01/03/2020','DE','01/01/2020    ','01/01/2020   ','2GFSDG37  ','Product3'),
('01/03/2020','DE','01/01/2020    ','01/01/2020   ','24GSFD1   ','Product1'),
('01/04/2020','DE','01/04/2020    ','01/01/2020   ','2GFSDG37  ','Product4'),
('01/04/2020','DE','01/04/2020     ','01/01/2020      ','23GSFDG5  ','Product6'),
('01/04/2020','DE','01/04/2020     ','01/01/2020      ','24GSFD1   ','Product1'),
('01/05/2020','DE','01/04/2020    ','01/01/2020   ','23GSDF6   ','Product3'),
('01/05/2020','DE','01/04/2020    ','01/01/2020   ','23GSDF6   ','Product9'),
('01/06/2020','DE','01/04/2020    ','01/01/2020   ','24GSFD1   ','Product8');

询问:

SELECT DISTINCT T1."Period",
    T1."Country",
    T1."Quarter",
    T1."Year",
    T1."Company",
    T2."Product"
FROM TMP_TEST1 AS T1 INNER JOIN TMP_TEST2 AS T2 
ON T1."Period" = T2."Period"
AND T1."Country"=T2."Country"
GROUP BY  1,2,3,4,5,6

使用此测试数据集,您将看到没有公司时我会丢失产品。我不知道如何打破这种关系。我希望我对你来说足够清楚。

标签: performancejoinsnowflake-cloud-data-platform

解决方案


首先,鉴于您显示的 2 个源表中的数据,还请提供您希望看到的结果。

对于您给出的查询,使用 ANSI SQL 的正确编写方法如下:

SELECT R."Period",R."Zone",R."Country",S."Quarter",S."Year",R."Company",S."Product"
FROM table1 AS R
INNER JOIN table2 AS S ON
R."Period" = S."Period"
AND R."Zone" = S."Zone"
AND R."Country"=S."Country"
 GROUP BY 1,2,3,4,5,6,7

重复我的问题(并添加更多)

  1. 目前查询需要多长时间?
  2. 您大概需要多长时间才能认为性能可以接受?
  3. 当您的查询中没有聚合函数时,为什么要使用 GROUP BY?如果您想要一个不同的列表(并且您的查询肯定会产生重复),请使用 SELECT DISTINCT...
  4. “笛卡尔计算”是什么意思?你的意思是笛卡尔连接,如果你这样做了,为什么你提到它们,因为你没有笛卡尔连接?

回应评论

ANSI SQL 连接更易于阅读(和调试),因为所有连接信息都在 JOIN 语句中,所有过滤条件都在 WHERE 语句中 - 而且它是行业标准,因此对您来说是个好主意,因为初学者,现在习惯使用它,而不是学习不好的做法。想象一下,如果您使用内/外/左/右连接混合连接 20 个表 - 您使用的语法将非常难以理解,而 ANSI SQL 连接语法将很容易理解。

  1. 根据您的源表,您仍然没有提供您期望看到的输出 - 所以任何试图帮助您的人都会猜测您想要实现的目标。
  2. 您也没有提供解释计划,因此没有人可以看到您的查询是如何执行的,因此问题可能是什么。在 Snowflake 中,转到 History,单击相关的 Query ID,单击 Profile,然后附上一个屏幕截图,显示正在运行的所有步骤、执行时间、统计信息等。

推荐阅读