选择视图包含dblink时,插入语句的性能较差

时间:2018-10-11 03:05:09

标签: oracle insert-into dblink hint

在Oracle 12.2中,使用Insert语句遇到了一些麻烦。 我有这样的查询:

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;

麻烦是:

  • 对于诸如APPEND,Driving_Site,Parallel甚至Nologing之类的Insert语句,提示不起作用。 200万条记录从远程表插入到本地表花了将近2个小时。 我尝试调试,select语句仅用8秒钟即可从远程表中获取200万条记录。
  • ViewA和ViewB可以使用任何提示吗?当我使用诸如Driving_Site之类的提示时,这是非常糟糕的性能(如果不使用,则是很好的性能)。由于公司规定,我不能在数据库代码上使用dblink而不是View。

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

1 个答案:

答案 0 :(得分:1)

我对您的评论对评论来说太长了,因此即使不是“这里就是您的解决方法”,也可以将其作为答案。我有两个想法给你。 HTH

  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;