海量数据更新最大的问题在于undo拓展的量,我们检查一下执行过程中的undo size情况。
SQL> select sum(bytes)/1024/1024 from dba_undo_extents where status='ACTIVE';
SUM(BYTES)/1024/1024
--------------------
SQL> select sum(bytes)/1024/1024 from dba_undo_extents where status='ACTIVE';
SUM(BYTES)/1024/1024
--------------------
16
SQL> select sum(bytes)/1024/1024 from dba_undo_extents where status='ACTIVE';
SUM(BYTES)/1024/1024
--------------------
10
每次的数据量都不大,说明每次都是一小块chunk的操作。也确定使用parallel执行的过程,是分步小块commit的过程。在job视图中,我们也可以明确的看出作为作业的信息。
SQL> select owner, job_name, JOB_ACTION, SCHEDULE_TYPE, state, last_start_date from dba_scheduler_jobs where job_name like 'TASK$_4%';
OWNER JOB_NAME JOB_ACTION SCHEDULE_TYPE STATE LAST_START_DATE
------- ----------- ------------------------------------------ ------------- --------------- -----------------------------------
SYS TASK$_4_2 DBMS_PARALLEL_EXECUTE.RUN_INTERNAL_WORKER IMMEDIATE RUNNING 10-2月 -14 01.48.34.947417 下午 PRC
SYS TASK$_4_1 DBMS_PARALLEL_EXECUTE.RUN_INTERNAL_WORKER IMMEDIATE RUNNING 10-2月 -14 01.48.34.730487 下午 PRC
注意:传统的并行进程v$px_process中没有看到数据信息,说明并行程序包并不是Oracle传统的数据库并行方案。
SQL> select * from v$px_process;
SERVER_NAME STATUS PID SPID SID SERIAL#
----------- --------- ---------- ------------------------ ---------- ----------
执行结束信息:
25 --Controller
26 n_try := 0;
27 n_status := dbms_parallel_execute.task_status(task_name => vc_task);
28 while (n_try<2 and n_status != dbms_parallel_execute.FINISHED) loop
29 dbms_parallel_execute.resume_task(task_name => vc_task);
30 n_status := dbms_parallel_execute.task_status(task_name => vc_task);
31 end loop;
32
33 --Deal with Result
34 dbms_parallel_execute.drop_task(task_name => vc_task);
35 end;
36 /
PL/SQL procedure successfully completed
Executed in 944.453 seconds
更新2G数据一共使用945s,合计约16分钟。
从上面的数据视图和调用过程,我们可以得到如下结论:
对dbms_parallel_execute执行包而言,通过确定chunk方法和chunk size,可以将一个很大的数据集合划分为若干各小chunk集合,分步进行操作处理。代码中设置的parallel_level,体现在设置Job的个数上。启动作业任务后,Oracle并不是启动传统的并行机制,而是在Job Schedule的基础上创建parallel_level个数的作业,类型为立即执行。多个作业分别执行各个chunk的小块工作。使用Job Schedule的一个好处在于可以方便的进行作业resume和start过程。
下面我们讨论by number col和by SQL两种执行方法。