引子:以前一直没太关注oracle并行这个特性。前几天一个兄弟碰到的一个问题,才让我觉得这个东西还是有很多需要注意的地方,有必要仔细熟悉下。其实 碰到的问题不复杂:
类似如下的一条语句:insert into xxxx select /*+parallel(a) */ * from xxx a;数据量大约在75G左右,这位兄弟从上午跑到下午还没跑完,过来问我咋回事,说平常2hrs能跑完的东西跑了好几个小时还撒动静。查看系统性能也比较 正常,cpu,io都不繁忙,平均READ速度在80M/s左右(勉强凑合),但平均写速度只有10M不到。等待事件里面大量的‘ ‘PX Deq Credit : send blkd ’,这里能看出并行出了问题,从而最后得知是并行用法有问题,修改之后 20分钟完成了该操作。正确的做法应该是:
alter session enable dml parallel;
insert /*+parallel(xxxx,4) */ into xxxx select /*+parallel(a) */ * from xxx a;
因为oracle默认并不会打开PDML,对DML语句必须手工启用。 另外不得不说的是,并行不是一个可扩展的特性,只有在数据仓库或作为DBA等少数人的工具在批量数据操作时利于充分利用资源,而在OLTP环境下使用并行 需要非常谨慎。事实上PDML还是有比较多的限制的,例如不支持触发器,引用约束,高级复制和分布式事务等特性,同时也会带来额外的空间占用,PDDL同 样是如此。有关Parallel excution可参考官方文档 ,在Thomas Kyte的新书《Expert Oracle Database architecture》也有精辟的讲述。
SQL> create table test3 parallel 4 as select * from test1;
表已创建。
SQL> select * from v$mystat where rownum=1;
SID STATISTIC# VALUE
---------- ---------- ----------
151 0 1
SQL>
然 后立刻在另一SESSION 乘上一个执行没结束,看下面,这么说是有4个并行的进程在处理了
SQL> select * from v$px_session;
SADDR SID SERIAL# QCSID QCSERIAL# QCINST_ID SERVER_GROUP SERVER_SET SERVER# DEGREE REQ_DEGREE
-------- ---------- ---------- ---------- ---------- ---------- ------------ ---------- ---------- ---------- ----------
6D31E434 131 16 151 107 1 1 1 1 4 4
6D32421C 136 11 151 107 1 1 1 2 4 4
6D3267AC 138 18 151 107 1 1 1 3 4 4
6D31F6FC 132 11 151 107 1 1 1 4 4 4
6D335BD4 151 107 151
SQL> select * from v$mystat where rownum=1;
SID STATISTIC# VALUE
---------- ---------- ----------
137 0 1
SQL>
我 加大后
SQL> /
SADDR SID SERIAL# QCSID QCSERIAL# QCINST_ID SERVER_GROUP SERVER_SET SERVER# DEGREE REQ_DEGREE
-------- ---------- ---------- ---------- ---------- ---------- ------------ ---------- ---------- ---------- ----------
6D31864C 126 10 151 107 1 1 1 1 7 10
6D31F6FC 132 17 151 107 1 1 1 2 7 10
6D32421C 136 15 151 107 1 1 1 3 7 10
6D3267AC 138 22 151 107 1 1 1 4 7 10
6D322F54 135 11 151 107 1 1 1 5 7 10
6D31E434 131 18 151 107 1 1 1 6 7 10
6D327A74 139 5 151 107 1 1 1 7 7 10
6D335BD4 151 107 151
已选择 8行。
SQL>
奇怪,怎么看只有7个,我那里可是写成
SQL> create table test4 parallel 10 as select * from test1;
表已创建。
怎么少了3 个?
不过我实际只有一个CPU的机器,这些说明什么问题呢?
BTW
SQL> SHOW Parameter parallel_max
NAME TYPE VALUE
------------------------------------ ---------------------- -------------------
parallel_max_servers integer 20
SQL>
这个并行度和你初始化参数有关。CPU_COUNT 、PARALLEL_THREADS_PER_CPU 等等都有关系。如果你建表的时候没有明确指定并行度,那么oracle会自动的根据需要设定并行度。