我想知道是否可以在循环中同时运行独立查询。例如:
begin
for I in (select class_id from school) loop
insert into mast_tab(
select * from class1);
insert into mast_tab(
select * from class2);
insert into mast_tab(
select * from class3);
insert into mast_tab(
select * from class4);
insert into mast_tab(
select * from class5);
commit;
end loop;
end;
在上面的块中,当循环条件为真时,将逐个执行所有查询。基于循环值,是否可以同时运行所有查询,而查询不相互依赖。它会减少五倍的时间。
答案 0 :(得分:1)
简短的回答是"不是真的",但你可以通过使用DBMS_SCHEDULER来创建和提交这些作为定时同时运行的作业来实现这一效果。 Clunky,你必须为等待所有人完成,处理单个或多个故障等事情编写代码。我不推荐它,但它是一个很好的技术练习,可以了解调度程序和作业控制。
您将使用此方法遇到另一个问题,因为他们正在写入同一个表,锁定/争用,这意味着您可能无法获得您认为的线性改进。您可以采取措施提高吞吐量,但这是另一个主题。
不同的方法怎么样?使用来自不同表的SELECT对同一个表有5个INSERT。根据您的示例,您可以尝试使用PARALLEL提示并将INSERT与SELECT查询组合为1 UNIONED:
INSERT /*+ PARALLEL ( mast_tab, 8 ) */
INTO mast_tab
SELECT * FROM class1
UNION ALL
SELECT * FROM class2
UNION ALL
SELECT * FROM class3
UNION ALL
SELECT * FROM class4
UNION ALL
SELECT * FROM class5
;
答案 1 :(得分:0)
你应该能够做到这一点,但我自己并没有写过这样的东西。我确实找到了关于如何在互联网上做类似事情的解释,所以你可能想阅读这些文章:
http://www.dba-oracle.com/plsql/t_plsql_parallel_functions.htm
http://www.dba-oracle.com/r_execute_pl_sql_in_parallel.htm
确保在提交更改之前构建一个检查以查看是否所有并行进程已实际完成。
编辑:在您给出的示例中,您将一堆不同的表插入到单个表中。将INSERT语句组合到一个语句中,然后让Oracle并行化做它的事情也可以为您带来性能提升。这并不总是可行的,但它在你的例子中。您的查询最终会如下所示:
BEGIN
FOR I IN (SELECT id FROM mast_tab)
LOOP
INSERT /*+ PARALLEL(mast_tab) */ INTO mast_tab
(SELECT /*+ PARALLEL(class1) */ * FROM class1
UNION ALL
SELECT /*+ PARALLEL(class2) */ * FROM class2
UNION ALL
SELECT /*+ PARALLEL(class3) */* FROM class3
UNION ALL
SELECT /*+ PARALLEL(class4) */* FROM class4
UNION ALL
SELECT /*+ PARALLEL(class5) */* FROM class5)
;
COMMIT;
END LOOP;
END;
答案 2 :(得分:-1)
尝试使用DBMS_SCHEDULER或DBMS_JOB包。 它允许将它作为可以并行运行的分离后台作业运行。