查询提示 - Oracle 多插入语句



在我的应用程序中,我必须添加许多记录。我使用以下结构:

   INSERT /*+ append parallel(t1, 4) parallel(t2, 4) */ ALL
   INTO t1 (col1, col2, col3) VALUES ('val1_1', 'val1_2', 'val1_3')
   INTO t2 (col1, col2, col3) VALUES ('val2_1', 'val2_2', 'val2_3')
   INTO t2 (col1, col2, col3) VALUES ('val3_1', 'val3_2', 'val3_3')
   .
   .
   .
SELECT 1 FROM DUAL;

我也在使用追加和并行提示。请注意,我在两个不同的表中插入数据。似乎并行被忽略了(DBA告诉我)。那么我怎么知道它是否被使用呢?是否可以在这种结构中使用并行提示?有效吗?

这可能足以让它工作:

alter session enable parallel dml;

您可以使用如下所示的查询来检查实际的并行度:

select px_servers_executions, v$sql.*
from v$sql where lower(sql_text) like '%insert%parallel%' order by last_load_time desc;

如果您仍然没有获得并行性,则可能有很多原因。 首先,请查看以下参数:

select * from v$parameter where name like 'parallel%'

但是您可能不希望插入语句具有并行性。 并行性具有大量开销,通常仅在处理数千或数百万条记录时才有用。

我猜你真正的问题是解析大型SQL语句的时候了。 多表插入尤其糟糕。 如果您尝试插入超过几百行,则查询将需要几秒钟的时间来解析。 根据您的 Oracle 版本,如果您尝试使用 501 表,它将永远挂起。 运行多个较小的查询比运行一个大型查询要快得多。 例如,5 个 100 行的插入比一个 500 行的插入运行速度快得多。 (通常,这与如何为 Oracle 进行性能调整完全相反。 这是一个特殊情况,因为存在与解析大型 SQL 语句相关的错误。

APPEND 提示仅受 INSERT 语句的子查询语法支持,而不支持 VALUES 子句。如果使用 VALUES 子句指定 APPEND 提示,则会忽略该提示,并使用常规插入。要将直接路径 INSERT 与 VALUES 子句一起使用,请参阅"APPEND_VALUES提示"。

在某些情况下,并行性被禁用。包括,从甲骨文文档:

DML 禁用并行性 对具有的表的操作 定义了触发器或引用 完整性约束。

这对我来说似乎是一个相当大的限制。表中是否有触发器或外键?

为 30 条记录启用并行性将浪费资源。并行性涉及昂贵的开销(拆分工作、分配进程、同步结果......),对于如此小的操作来说,这是不值得的。

我想如果你想优化它那么糟糕,你会执行这个语句数百万次。在这种情况下,找到一种方法将这百万条语句转换为大型集合操作可能会更有效 - 这可以很好地从并行性中受益。


更新:另一个想法可能是使用多个会话运行语句,有效地实现 DIY 并行性。您能否设计流程,以便多个会话读取输入数据并同时插入?

最新更新