我在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;
视图 A 和 B 的查询是这样的:
Select columnA, columnB, columnC FROM REMOTE.CUSTOMERS@DBLCUSTOMER;
麻烦是:
- 提示不适用于插入语句,如 APPEND、Driving_Site、并行甚至 Nologing。从远程表插入到本地表的 200 万条记录需要将近 2 个小时。 我尝试调试,select 语句只需 8 秒即可从远程表中获取 200 万条记录。
- 任何提示都可以用于视图A和视图B吗?当我使用诸如Driving_Site之类的提示时,性能非常糟糕(如果我不使用,则性能很好(。由于公司规则,我不能使用 dblink 而不是块代码上的视图。
在这种情况下,是否有任何解决方案可以提高性能?
我对你的评论太长了,无法发表评论,所以在这里你可以把它作为一个答案,即使这不是"这是你的修复"类型的答案。我有两个想法给你。呵呵
- 也许当您说 SELECT 只需要 2 秒时,您不是在获取所有行,而是在获取前 50 行?如果使用 Oracle SQL Developer,则可以单击结果集,然后按 Ctrl+A 查看提取所有行所需的时间。
- 关于您的提示不起作用以及选择在插入时需要更长的时间,我可以从这里提供以下报价:https://jonathanlewis.wordpress.com/2008/12/05/distributed-dml/
分布式 DML 语句必须在 DML 目标所在的数据库上执行。DRIVING_SITE提示无法覆盖此提示。
因此,在分布式 DML 场景中,oracle 会拉取所有内容(连接之前的基表数据(,并在本地执行连接等。但还是有希望的,引用同样的链接:
如果要使此示例远程加入,则必须在远程站点上创建联接视图,并查询该视图。
这是我的做法。此示例适用于活动 DG,我希望 DG 和 RDS 上的所有工作负载仅发生插入,并且仅通过数据库链路传输插入的行:
-- 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;