oracle dbms_parallel_execute,使用dbms_parallel_execute来完成DML的并行

在工作中使用并行可以极大的提高工作效率。可以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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值