问题描述
我正在尝试编写Oracle过程以将数据从远程数据链接合并到本地表中。各个部分的工作速度很快,但在一起时它们会超时。这是我正在尝试的简化版本。
有效方法:
Select distinct ProjectID from Project where LastUpdated < (sysdate - 6/24);
-瞬间完成。
Merge into project
using (select /*+DRIVING_SITE(remoteCompData)*/
rp.projectID,rp.otherdata
FROM Them.Remote_Data@DBLink rd
WHERE rd.projectID in (1,2,3)) sourceData -- hardcoded IDs
On (rd.projectID = project.projectID)
When matched...
-当ID进行硬编码时,合并语句会快速工作
行不通的方法:将以上两个语句组合在一起。
Merge into project
using (select /*+DRIVING_SITE(rd)*/ -- driving site helps when this piece is extracted from the larger statement
rp.projectID,rp.otherdata
FROM Them.Remote_Data@DBLink rd
WHERE rd.projectID in --in statement that works quickly by itself.
(Select distinct ProjectID from Project where LastUpdated < (sysdate - 6/24))
-- This select in the in clause one returns 10 rows. Its a test database.
On (rd.projectID = project.projectID)
)
When matched...
-当我在sql Developer中运行此语句时,这就是我在不进行数据更新的情况下所获得的一切 连接到本地数据库。 流程已退出。 与本地数据库断开连接。
我还尝试将in语句放入with语句中,希望它的执行方式有所不同,但无效。
任何前进的方向将不胜感激。 谢谢。
解决方法
/*+DRIVING_SITE(rd)*/
提示不适用于MERGE,因为该操作必须在合并表所在的数据库中运行。在这种情况下是本地数据库。这意味着来自远程表的整个结果集将跨数据库链接拉出,然后根据本地表中的数据进行过滤。
因此,丢弃提示。我还建议您将IN子句转换为联接:
Merge into project p
using (select rp.projectID,rp.otherdata
FROM Project ld
inner join Them.Remote_Data@DBLink rd
on rd.projectID = ld.projectID
where ld.LastUpdated < (sysdate - 6/24)) q
-- This select in the in clause one returns 10 rows. Its a test database.
On (q.projectID = p.projectID)
)
请记住,对性能调优问题的解答没有足够的详细信息,只是猜测。
,我发现你的问题有同样的问题。是的,当查询包含在 using
命令的 merge
子句中时,查询中的提示会被忽略。
就我而言,我创建了工作表,例如 w_remote_data
,并将合并命令拆分为两个命令:(1) 填充工作表,(2) 调用 merge
命令 {{1 }} 工作表。
陷阱是,我们不能简单地使用命令 using
或 create w_remote_data as select /*+DRIVING_SITE(rd)*/ ...
来填充工作表。这两个命令都是有效的,但它们很慢——提示也不适用,所以我们不会解决这个问题。解决方案是在 PLSQL 中:使用中间集合在 insert into w_remote_data select /*+DRIVING_SITE(rd)*/ ...
子句中收集查询结果。请参见示例(为简单起见,我假设 using
与 w_remote_data
具有相同的结构,否则我们必须定义自定义记录而不是 remote_data
):
%rowtype
我的案例是 ETL 脚本,我可以信赖它不会并行运行。否则我们将不得不处理临时(会话私有)表,如果它适用于它们,我没有尝试。