【发布时间】:2018-12-14 12:20:08
【问题描述】:
我有这个程序试图在 oracle 环境 (11.2) 中加载 table5,它与相同的表(每个表都有 500 万条记录)连接超过 3 次,并且需要超过 2 个小时。
create or replace PROCEDURE PROC1 AS
BEGIN
INSERT INTO table4
SELECT
lt_sn_issues.DA_SECTOR,
lt_sn_issues.DA_REGION,
tmp_ft_lt_scan_id.PROJ,
tmp_ft_lt_scan_id.SOL,
COUNT(ft_sn_issues.ISS_ID),
COUNT(DISTINCT ft_sn_issues.FL_ID),
COUNT(DISTINCT ft_fl_scans.FL_ID),
PROJ_files_count.COUNT,
COUNT(lt_sn_issues.ISS_ID),
COUNT(DISTINCT lt_sn_issues.FL_ID),
COUNT(DISTINCT lt_fl_scans.FL_ID),
COUNT(pr_sn_issues.ISS_ID),
COUNT(DISTINCT pr_sn_issues.FL_ID),
COUNT(DISTINCT pr_fl_issues.FL_ID),
CURRENT_DATE
FROM
tmp_ft_lt_scan_id
JOIN table1 ft_sn_issues ON ft_sn_issues.SCAN_ID = tmp_ft_lt_scan_id.FIRST_SCAN_ID
JOIN table1 lt_sn_issues ON lt_sn_issues.SCAN_ID = tmp_ft_lt_scan_id.FIRST_SCAN_ID
LEFT JOIN table1 pr_sn_issues
ON pr_sn_issues.SCAN_ID = tmp_ft_lt_scan_id.FIRST_SCAN_ID
JOIN table2@dblink ft_fl_scans ON ft_fl_scans.SCAN_ID = tmp_ft_lt_scan_id.FIRST_SCAN_ID
JOIN table2@dblink lt_fl_scans ON lt_fl_scans.SCAN_ID = tmp_ft_lt_scan_id.FIRST_SCAN_ID
LEFT JOIN table2@dblink pr_fl_issues ON pr_fl_issues.SCAN_ID = tmp_ft_lt_scan_id.FIRST_SCAN_ID
JOIN (
SELECT
FL_INFOR.PROJ PROJ,
FL_INFOR.SOL SOL,
COUNT(DISTINCT FL_INFOR.PATH) COUNT
FROM FL_INFOR@DBLINK
GROUP BY FL_INFOR.PROJ,L_INFOR.SOL
) PROJ_files_count
ON PROJ_files_count.PROJ = tmp_ft_lt_scan_id.PROJ
where rownum<=100
GROUP BY
lt_sn_issues.DA_SECTOR,
lt_sn_issues.DA_REGION,
tmp_ft_lt_scan_id.PROJ,
tmp_ft_lt_scan_id.SOL,
PROJ_files_count.COUNT;
【问题讨论】:
-
不只是将 5m 条记录的同一个表连接 3 次,而是 远程数据库中的同一个表。哦,男孩。
-
但是你为什么要这样做呢?连接条件相同,因此您似乎只是选择了 3 次相同的记录。
-
我们引用了来自同一个表的三个不同的连接,用于检索 3 个不同列的值并通过别名进行区分。
-
但它是 同一组行 3 次。不知道这里发生了什么。您的查询连接了三次
table1和三次table2@dblink。但始终使用相同的连接标准tmp_ft_lt_scan_id.FIRST_SCAN_ID并且没有其他过滤器。所以每张表的同一组记录 3 次。因此,您在此处发布的内容不是您的真实代码,这意味着我们没有机会为您提供建议。或者您的查询存在缺陷并生成大量笛卡尔积,这至少可以解释为什么性能如此差:太多不必要的工作。 -
我已经发布了实际代码,但表名和列名不同。我们如何在这里避免大量的笛卡尔积?
标签: sql oracle performance plsql query-optimization