Oracle SQL: JOIN by dblink



我在Oracle DB中使用下一个SQL查询:

    SELECT T1.*,
           T3.*
    FROM MyTable1 T1
    INNER JOIN MyTable2 T2 ON T2.Id1 = T1.Id
    LEFT JOIN MyTable3@dblink1 T3 ON T3.Id2 = T2.Id

此查询非常简单快速(大约 1 分钟,T1 包含大约 100 万行,T3 包含大约 1000 万行)。现在我想使用 dblink1 中的 MyTable4 来过滤选定的行数据。为此,我使用子查询:

        SELECT T1.*,
               T3.*
        FROM MyTable1 T1
        INNER JOIN MyTable2 T2 ON T2.Id1 = T1.Id
        LEFT JOIN (SELECT Sub_T1.*
                        FROM MyTable3@dblink1 Sub_T1
                        INNER JOIN MyTable4@dblink1 Sub_T2 ON Sub_T2.Id3 = Sub_T1.Id
                        WHERE
                                    Sub_T2.MyColumn1 = 'required value') T3 ON T3.Id2 = T2.Id

但是这个查询太慢了(超过 20 分钟)。如果我将此查询重写为:

SELECT T1.*,
       T3.*
FROM MyTable1 T1
INNER JOIN MyTable2 T2 ON T2.Id1 = T1.Id
LEFT JOIN  MyTable3@dblink1 T3 ON T3.Id2 = T2.Id
LEFT JOIN MyTable4@dblink1 T4 ON T4.Id3 = T3.Id
WHERE
        T4.MyColumn1 = 'required value'

然后我的查询再次快速工作,但我不喜欢结果(如果 WHERE 返回 false,我希望将 T3 的列视为空)。如何改进我的第二个查询,以加快它?

用括号括查询是否可以解决问题?

SELECT T1.*,
       T3.*
FROM MyTable1 T1 INNER JOIN
     MyTable2 T2
     ON T2.Id1 = T1.Id LEFT JOIN 
     (MyTable3@dblink1 T3 JOIN
      MyTable4@dblink1 T4
      ON T4.Id3 = T3.Id AND
         T4.MyColumn1 = 'required value'
     )
     ON T3.Id2 = T2.Id;

或者,还有:

SELECT T1.*,
       T3.*
FROM MyTable1 T1 INNER JOIN
     MyTable2 T2
     ON T2.Id1 = T1.Id LEFT JOIN 
     MyTable3@dblink1 T3
     ON T3.Id2 = T2.Id
        EXISTS (SELECT 1 FROM MyTable4@dblink1 T4 WHERE T4.Id3 = T3.Id AND T4.MyColumn1 = 'required value'
               )

如果您仍在这里寻找解决方案,请尝试使用您的子查询并将其转换为通过"dblink1"数据库链接链接到的数据库的视图。 然后针对视图执行左联接,而不是直接针对基础表执行左联接。

像这样:

在通过 dblink1 链接到的数据库上,创建以下视图:

CREATE OR REPLACE VIEW MYVIEW 
AS
SELECT Sub_T1.*
   FROM MyTable3   Sub_T1
   INNER JOIN MyTable4 Sub_T2 
         ON Sub_T2.Id3 = Sub_T1.Id
   WHERE
      Sub_T2.MyColumn1 = 'required value';

然后,回到另一边,将查询重写为:

 SELECT T1.*,
        T3.*
    FROM MyTable1 T1
        INNER JOIN MyTable2 T2 
              ON T2.Id1 = T1.Id
        LEFT JOIN MyView@dblink1 T3 
              ON T3.Id2 = T2.Id;

最新更新