【问题标题】:Stored procedure with multiple joins with same tables具有相同表的多个连接的存储过程
【发布时间】: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


【解决方案1】:

如果问题是性能,首先将索引添加到tmp_ft_lt_scan_id.FIRST_SCAN_ID 列。

【讨论】:

  • 纯属猜测。也许你是对的,也许你是错的。 OP为任何人提供的信息太少,无法提出明智的建议。然而,看起来他们正在离开tmp_ft_lt_scan_id 并将其他表中的行与其行匹配。因此,对该表进行全表扫描将是正确的访问路径,而我们对索引的最大期望是它没有任何区别。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-08
  • 2021-11-30
  • 2016-10-05
  • 1970-01-01
  • 1970-01-01
  • 2017-07-12
  • 1970-01-01
相关资源
最近更新 更多