我在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;