performance - 连接的性能问题
问题描述
我加入了两张表现不佳的桌子。
表格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
使用此测试数据集,您将看到没有公司时我会丢失产品。我不知道如何打破这种关系。我希望我对你来说足够清楚。
解决方案
首先,鉴于您显示的 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
重复我的问题(并添加更多)
- 目前查询需要多长时间?
- 您大概需要多长时间才能认为性能可以接受?
- 当您的查询中没有聚合函数时,为什么要使用 GROUP BY?如果您想要一个不同的列表(并且您的查询肯定会产生重复),请使用 SELECT DISTINCT...
- “笛卡尔计算”是什么意思?你的意思是笛卡尔连接,如果你这样做了,为什么你提到它们,因为你没有笛卡尔连接?
回应评论
ANSI SQL 连接更易于阅读(和调试),因为所有连接信息都在 JOIN 语句中,所有过滤条件都在 WHERE 语句中 - 而且它是行业标准,因此对您来说是个好主意,因为初学者,现在习惯使用它,而不是学习不好的做法。想象一下,如果您使用内/外/左/右连接混合连接 20 个表 - 您使用的语法将非常难以理解,而 ANSI SQL 连接语法将很容易理解。
- 根据您的源表,您仍然没有提供您期望看到的输出 - 所以任何试图帮助您的人都会猜测您想要实现的目标。
- 您也没有提供解释计划,因此没有人可以看到您的查询是如何执行的,因此问题可能是什么。在 Snowflake 中,转到 History,单击相关的 Query ID,单击 Profile,然后附上一个屏幕截图,显示正在运行的所有步骤、执行时间、统计信息等。
推荐阅读
- amazon-web-services - aws lambda - 如果手动创建 s3 存储桶,如何使用 cloudformation 添加 s3 触发器
- c# - 在 C# 中检查对象的编译时类型
- java - 为什么 Selenium 在忙于加载另一个页面时无法执行 driver.get(URL)?
- python - 如何计算人脸识别系统的准确率?
- python - 如何在 pytorch 中实现 tf.nn.in_top_k
- typescript - 如何使用“p-waterfall”TypeScript 类型
- angular - 使用异步/等待而不是订阅传递变量
- flutter - 通过 ChangeNotifierProvider 加载状态未显示
- java - Java JUnit:使用临时文件测试readFile方法,无法解析FileUtils
- python - 从 Python 中的系统命令捕获 INFO/DEBUG 输出