使用dbms_parallel_execute來完成DML的並行

dbhelper發表於2014-11-26

在工作中使用並行可以極大的提高工作效率。可以Object,session.hint級別引入並行。可以使大量的資料處理更加高效。

比如現在有一個表 t 有1000萬行,如果想以這個表為基礎,把資料選擇性的插入另外一個表t2,
使用Insert into t2 select *from t;
使用並行來處理也沒有問題,但是如果使用dbms_parallel_execute也是一種很不錯的選擇。
使用dbms_parallel_execute的實現方式和parallel還有一定的差別。
這個包在11g開始引入,可能初次接觸的時候會被它大量的功能所淹沒,不知道從何開始。

舉個例子來說明一下。
我們建立一個表 t,限於環境的情況,目前做一個百萬級別的資料dml操作,使用dbms_parallel_execute來完成。
建立表t.

SQL> drop table t;

Table dropped.

SQL> create table t as select object_id,object_name from dba_objects;

Table created.

建立表t2,我們專門專門多加了一個欄位。session_id。到時候會有用處。

SQL> drop table t2;

Table dropped.

SQL> create table t2 as select t1.*,0 session_id from t t1 where 1=0;

Table created.

使用如下的儲存過程來模擬一個dml的處理過程。傳入的引數,是根據rowid來處理。
create or replace procedure serial(p_lo_rid in rowid,p_hi_rid in rowid)
is
begin
for x in (select object_id object_id,object_name object_name from t where rowid between p_lo_rid and p_hi_rid)
loop
insert into t2(object_id,object_name,session_id)
values(x.object_id,x.object_name,sys_context('userenv','sessionid'));
end loop;
end;
/

使用dbms_parallel_execute來建立一個Job,以1萬條資料分單位進行資料的rowid切分。

begin
dbms_parallel_execute.create_task('PROCESS TASK');
dbms_parallel_execute.create_chunks_by_rowid
( task_name=>'PROCESS TASK',
  table_owner=>user,
  table_name=>'T',
  by_row=>false,
  chunk_size=>10000);
  end;
 /

透過dba_parallel_execute_chunks可以檢視到切分後的rowid情況。

set pages 200
select *from (
select chunk_id,status,start_rowid,end_rowid
from dba_parallel_execute_chunks
where task_name='PROCESS TASK'
order by chunk_id
);

檢視切分後的情況,我們可以把切分後的每一個子塊稱為chunk。可以透過這個語句來簡單的監控進度。
 CHUNK_ID STATUS               START_ROWID        END_ROWID
---------- -------------------- ------------------ ------------------
       600 UNASSIGNED           AAAEQCAAFAAAACAAAA AAAEQCAAFAAAAD/CcP
       601 UNASSIGNED           AAAEQCAAFAAAAEAAAA AAAEQCAAFAAAAF/CcP
       602 UNASSIGNED           AAAEQCAAFAAAAGAAAA AAAEQCAAFAAAAH/CcP
       603 UNASSIGNED           AAAEQCAAFAAAAIAAAA AAAEQCAAFAAAAJ/CcP
       604 UNASSIGNED           AAAEQCAAFAAAAKAAAA AAAEQCAAFAAAAL/CcP
       605 UNASSIGNED           AAAEQCAAFAAAAWAAAA AAAEQCAAFAAAAX/CcP
       606 UNASSIGNED           AAAEQCAAFAAAAYAAAA AAAEQCAAFAAAAZ/CcP
       607 UNASSIGNED           AAAEQCAAFAAAAaAAAA AAAEQCAAFAAAAb/CcP
       608 UNASSIGNED           AAAEQCAAFAAAAcAAAA AAAEQCAAFAAAAd/CcP
       609 UNASSIGNED           AAAEQCAAFAAAEsYAAA AAAEQCAAFAAAEsfCcP
       610 UNASSIGNED           AAAEQCAAFAAAEsgAAA AAAEQCAAFAAAEsnCcP

可以使用如下的部分來開始處理資料。啟用了4個並行,並行度可以情況來提高。:start_id,:end_id是上面對應的rowid.

begin
dbms_parallel_execute.run_task
(task_name=>'PROCESS TASK',
sql_stmt=>'begin serial(:start_id,:end_id); end;',
language_flag=>DBMS_SQL.NATIVE,
parallel_level=>4);
end;
/



select *from (
select chunk_id,status,start_rowid,end_rowid
from dba_parallel_execute_chunks
where task_name='PROCESS TASK'
order by chunk_id
);

資料處理的進度可以檢視得到。
 CHUNK_ID STATUS               START_ROWID        END_ROWID
---------- -------------------- ------------------ ------------------
       600 PROCESSED            AAAEQCAAFAAAACAAAA AAAEQCAAFAAAAD/CcP
       601 PROCESSED            AAAEQCAAFAAAAEAAAA AAAEQCAAFAAAAF/CcP
       602 PROCESSED            AAAEQCAAFAAAAGAAAA AAAEQCAAFAAAAH/CcP
       603 PROCESSED            AAAEQCAAFAAAAIAAAA AAAEQCAAFAAAAJ/CcP
       604 PROCESSED            AAAEQCAAFAAAAKAAAA AAAEQCAAFAAAAL/CcP
       605 PROCESSED            AAAEQCAAFAAAAWAAAA AAAEQCAAFAAAAX/CcP
       606 PROCESSED            AAAEQCAAFAAAAYAAAA AAAEQCAAFAAAAZ/CcP
       607 PROCESSED            AAAEQCAAFAAAAaAAAA AAAEQCAAFAAAAb/CcP
       608 PROCESSED            AAAEQCAAFAAAAcAAAA AAAEQCAAFAAAAd/CcP

處理完資料之後,就可以刪除這個job了。

begin
dbms_parallel_execute.drop_task('PROCESS TASK');
end;
/


我們可以在t2的新增列中看到每個對應的parallel處理的資料情況,可以看到資料的處理還是很平均的。
select session_id,count(*)
from t2
group by session_id
order by session_id;

SESSION_ID   COUNT(*)
---------- ----------
   1670371     357834
   1670372     370487
   1670373     403604
   1670374     404679


在資料處理的時候。可以看到dbms_parallel_execute後臺啟用的處理程式和並行還是有一些不同的。
啟用了4個並行之後,看到都是j00這樣的程式。

top - 06:31:03 up 1 day,  5:21,  2 users,  load average: 3.97, 1.55, 0.61
Tasks: 167 total,   4 running, 163 sleeping,   0 stopped,   0 zombie
Cpu(s): 60.7%us,  7.7%sy,  0.0%ni,  1.0%id, 28.9%wa,  0.2%hi,  1.5%si,  0.0%st
Mem:   2030124k total,  1293220k used,   736904k free,   358400k buffers
Swap:  4063224k total,        0k used,  4063224k free,   476552k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                   
32630 ora11g    20   0  530m  67m  64m D 55.2  3.4   0:48.34 ora_j000_TEST01                                                                                           
32634 ora11g    20   0  529m  60m  57m R 38.4  3.0   0:46.88 ora_j002_TEST01                                                                                           
32632 ora11g    20   0  529m  62m  59m R 24.8  3.2   0:44.54 ora_j001_TEST01                                                                                           
32636 ora11g    20   0  529m  59m  56m R 17.5  3.0   0:44.88 ora_j003_TEST01                                                                                           
 2295 ora11g    20   0  541m  79m  67m D  1.3  4.0   0:11.93 ora_dbw0_TEST01                                                                                           
32706 ora11g    20   0 14940 1240  904 R  1.0  0.1   0:00.39 top -c                                                                                                    
  825 root      20   0     0    0    0 S  0.3  0.0   0:18.85 [jbd2/sdb3-8]  

如果調高parallel從4到16,可以看到j00的程式相應的增加了。

top - 06:32:59 up 1 day,  5:23,  2 users,  load average: 1.31, 1.29, 0.63
Tasks: 182 total,   4 running, 178 sleeping,   0 stopped,   0 zombie
Cpu(s): 77.2%us, 21.2%sy,  0.0%ni,  1.2%id,  0.2%wa,  0.0%hi,  0.2%si,  0.0%st
Mem:   2030124k total,  1345284k used,   684840k free,   358500k buffers
Swap:  4063224k total,        0k used,  4063224k free,   476800k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                   
  404 ora11g    20   0  530m  39m  36m R 23.4  2.0   0:01.75 ora_j010_TEST01                                                                                           
  392 ora11g    20   0  529m  33m  30m S 17.1  1.7   0:01.39 ora_j004_TEST01                                                                                           
  402 ora11g    20   0  529m  31m  28m R 16.1  1.6   0:00.86 ora_j009_TEST01                                                                                           
  384 ora11g    20   0  530m  35m  32m S 12.2  1.8   0:01.21 ora_j000_TEST01                                                                                           
  386 ora11g    20   0  529m  32m  29m S 11.9  1.6   0:01.11 ora_j001_TEST01                                                                                           
  422 root      20   0  122m  19m  10m S 11.5  1.0   0:00.35 /u04/app/11.2.0/grid/bin/crsctl.bin check has                                                             
  394 ora11g    20   0  529m  31m  29m S 10.5  1.6   0:00.86 ora_j005_TEST01                                                                                           
  410 ora11g    20   0  530m  31m  28m R 10.5  1.6   0:00.63 ora_j013_TEST01                                                                                           
  408 ora11g    20   0  529m  32m  29m S  9.6  1.6   0:00.93 ora_j012_TEST01                                                                                           
  388 ora11g    20   0  529m  32m  29m S  8.9  1.6   0:01.14 ora_j002_TEST01                                                                                           
  398 ora11g    20   0  530m  32m  29m S  8.6  1.6   0:00.98 ora_j007_TEST01                                                                                           
  390 ora11g    20   0  529m  31m  28m S  7.6  1.6   0:00.74 ora_j003_TEST01                                                                                           
  396 ora11g    20   0  529m  32m  29m S  7.2  1.6   0:01.04 ora_j006_TEST01                                                                                           
  406 ora11g    20   0  530m  30m  27m S  5.6  1.5   0:00.49 ora_j011_TEST01                                                                                           
  414 ora11g    20   0  529m  29m  26m S  5.6  1.5   0:00.45 ora_j015_TEST01                                                                                           
  400 ora11g    20   0  529m  30m  27m S  4.9  1.5   0:00.64 ora_j008_TEST01                                                                                           
  412 ora11g    20   0  530m  30m  27m S  4.6  1.5   0:00.63 ora_j014_TEST01

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8494287/viewspace-1347020/,如需轉載,請註明出處,否則將追究法律責任。

相關文章