我建议使用DBMS_PARALLEL_EXECUTE
. 主会话等待子并行会话完成。有统计和结果的方便视图 -user_parallel_execute_chunks
和user_parallel_execute_tasks
. 我们在项目中使用它,觉得很方便。
有一点是,这个包需要分块,只能通过 rowid 或数字来完成。所以首先你必须创建一个接受数字的过程。这是适合您的情况:
create or replace procedure engineering_parallel(
iLaunchType number,
idx number
)
is
begin
if iLaunchType = 1 then
engineering('CONSERVATIVE',idx);
elsif iLaunchType = 2 then
engineering('INTERMEDIATE',idx);
elsif iLaunchType = 3 then
engineering('AGGRESSIVE',idx);
end if;
end;
在这里,您将找到一个在匿名 pl/sql 块中启动您的案例的示例,您可以轻松地将其转换为engineering_all
过程:
declare
-- idx parameter
idx number := 0;
-- unique parallel task name
sTaskName varchar2(32767) := 'ENGINEERING-'||to_char(sysdate,'yyyy-mm-dd-hh24-mi-ss');
-- this is where you store the query to split into chunks
sChunkSQL varchar2(32767) := 'select level start_id, '||idx||' end_id'||chr(10)||
'from dual connect by level <= 3';
-- this is the procedure call
sParallelSQL varchar2(32767) := 'begin engineering_parallel(:start_id,:end_id); end;';
-- parallel degree
iParalleDegree number := 3;
begin
-- create a task
DBMS_PARALLEL_EXECUTE.create_task(task_name => sTaskName);
-- chunking
DBMS_PARALLEL_EXECUTE.create_chunks_by_sql(
task_name => sTaskName,
sql_stmt => sChunkSQL,
by_rowid => FALSE
);
-- launch. current session waits till all child parallel sessions are finished
DBMS_PARALLEL_EXECUTE.run_task(
task_name => sTaskName,
sql_stmt => sParallelSQL,
language_flag => DBMS_SQL.NATIVE,
parallel_level => iParalleDegree
);
dbms_output.put_line(
'Job is finished.'||
'Check user_parallel_execute_chunks, user_parallel_execute_tasks for the task '||
sTaskName
);
end;
最后一点要考虑 - 检查您的版本是否包含错误 18966843的修复:DBMS_PARALLEL_EXECUTE PERFORMANCE DELAY AFTER UPGRADE TO 11.2.0.4 我们在 12.1 中遇到过它,但有修复它的补丁。如果它不是固定的,那么你有可能最后的平行度将低于要求(下降到 1)。