首页 > 解决方案 > 选择视图包含 dblink 时插入语句性能不佳

问题描述

我在 oracle 12.2 中的插入语句遇到了一些麻烦。我有这样的查询:

INSERT INTO LOCAL.TABLE_1 ( column1, column2....) 
SELECT  column1, column2
FROM (BLOCK CODE WITH SELECT AND INNER JOIN)
(
INNER JOIN (SELECT columnx, columny, columnz,columna, columnb...
FROM (SELECT columnx, columny, columnz FROM LOCAL.ViewA WHERE....) S
INNER JOIN (SELECT columna, columnb FROM LOCAL.ViewB WHERE....)D 
ON ..... )
)A WHERE b = 1;

ViewA 和 B 的查询如下:

Select columnA, columnB, columnC FROM REMOTE.CUSTOMERS@DBLCUSTOMER;

烦恼是:

在这种情况下是否有任何解决方案可以提高性能?

标签: oracleinsert-intodblinkhint

解决方案


我对您的评论对于评论来说太长了,所以在这里您可以将其作为答案,即使这不是“这是您的解决方法”之类的答案。我有两个想法给你。高温高压

  1. 也许当您说 SELECT 只需要 2 秒时,您并没有获取所有行,而是只获取前 50 行?如果您使用 Oracle SQL Developer,您可以单击结果集,然后按 Ctrl+A 以查看获取所有行需要多长时间。
  2. 关于您的提示不起作用以及当它是插入的一部分时选择需要更长的时间,我可以从这里提供这个引用:https ://jonathanlewis.wordpress.com/2008/12/05/distributed-dml/

分布式 DML 语句必须在 DML 目标所在的数据库上执行。DRIVING_SITE 提示不能覆盖它。

因此,在分布式 DML 场景中,oracle 会提取所有内容(连接之前的基表数据)并在本地进行连接等。但是有希望,引用相同的链接:

如果您想让这个示例远程连接,您必须在远程站点创建一个连接视图,并查询该视图。

这是我的做法。此示例适用于活动 DG,我希望 DG 和 RDS 上的所有工作负载仅发生插入,并且只有插入的行通过 DB 链接传输:

-- RDS
-- First we create the results table on the RDS
create table your_schema.your_table [...]


-- RDS (Due to DG I have to create it on RDS and it makes it's way to the DG)
-- Now we create a VIEW with your huge long running query
create view your_schema.your_view as
select  [...];  -- your huge long running query is here


-- DG
-- Now you fill the RDS Table you created. As the results come from a VIEW and the query is executed on DG, all the workload is done on DG
insert into your_schema.your_table@DBLINK_TO_RDS
select  * from your_schema.your_view;
commit;

在 RDS 的执行计划中,您会看到所有工作都在 DG 上完成。您只能看到“常规加载表”和“远程”。在 DG 的执行计划中,你会看到所有的大连接和东西。

您还可以检查 active_session_history 以了解每个系统上产生的工作负载:

select 
sum(TM_DELTA_TIME), sum(TM_DELTA_CPU_TIME), sum(TM_DELTA_DB_TIME), sum(DELTA_READ_IO_REQUESTS), sum(DELTA_WRITE_IO_REQUESTS), sum(DELTA_READ_IO_BYTES),
sum(DELTA_WRITE_IO_BYTES), sum(DELTA_INTERCONNECT_IO_BYTES), max(PGA_ALLOCATED), max(TEMP_SPACE_ALLOCATED)
from gv$active_session_history where session_id = 3X5 and SESSION_SERIAL# = 2XXX0 and SAMPLE_ID > 4XXXXX6 and sample_id <= 4XXXXX9;

推荐阅读