Swa*_*han 1 oracle parallel-processing plsql for-loop
我正在循环遍历表列表并更新每个表中的列列表。是否可以并行执行循环,即一次更新多个表。
FOR Table_rec IN Table_list_cur
LOOP
--Check if the table is partitioned
IF Check_if_partitioned (Table_rec.Table_name, Table_rec.Owner)
THEN
--If Yes, loop through each parition
EXECUTE IMMEDIATE
'Select partition_name from USER_TAB_PARTITIONS where table_name = '''
|| Table_rec.Table_name
|| ''' and owner = '''
|| Table_rec.Owner
|| ''''
BULK COLLECT INTO L_part;
FOR I IN L_part.FIRST .. L_part.LAST
LOOP
--Update each parition
DBMS_OUTPUT.Put_line ('V_sql_stmt' || V_sql_stmt);
V_sql_stmt :=
'UPDATE /*+ PARALLEL(upd_tbl,4) */ '
|| Table_rec.Table_name
|| ' PARTITION ('
|| L_part (I)
|| ') upd_tbl'
|| ' SET '
|| V_sql_stmt_col_list;
DBMS_OUTPUT.Put_line ('V_sql_stmt' || V_sql_stmt);
EXECUTE IMMEDIATE V_sql_stmt;
END IF;
END LOOP;
END LOOP;
Run Code Online (Sandbox Code Playgroud)
不直接,不。
您可以获取循环的核心内容,将其分解为存储过程调用,然后提交一系列作业来执行异步运行的实际处理。使用该dbms_job包使作业提交成为事务的一部分,看起来像
CREATE OR REPLACE PROCEDURE do_update( p_owner IN VARCHAR2,
p_table_name IN VARCHAR2 )
AS
BEGIN
<<your dynamic SQL>>
END;
Run Code Online (Sandbox Code Playgroud)
然后运行循环来提交作业
FOR Table_rec IN Table_list_cur
LOOP
--Check if the table is partitioned
IF Check_if_partitioned (Table_rec.Table_name, Table_rec.Owner)
THEN
dbms_job.submit( l_jobno,
'begin do_update( ''' || table_rec.owner || ''', ''' || table_rec.table_name || '''); end;' );
END IF;
END LOOP;
commit;
Run Code Online (Sandbox Code Playgroud)
一旦commit运行,各个表作业将开始运行(运行多少个由参数控制job_queue_processes),而其余表作业则排队。
现在,话虽如此,你的方法似乎有点不对劲。首先,显式指定分区名称几乎没有用。您几乎肯定希望提交单个UPDATE语句,省略分区名称,并让 Oracle 并行更新各个分区。每个分区运行一个更新语句反而违背了分区的目的。如果您确实希望每个分区有 4 个并行线程,您可能不希望其中许多更新并行运行。并行性的要点是可以允许一条语句消耗大部分系统资源。如果您确实想要同时运行 16 个分区级更新,并且每个更新运行 4 个从属设备,那么让 Oracle 为单个更新运行 64 个从属设备(或者您真正想要的任何数量的从属设备)会更有意义。专注于这个特定的任务取决于您想为系统必须做的其他事情留下多少资源)。
| 归档时间: |
|
| 查看次数: |
4909 次 |
| 最近记录: |