类似如下的一条语句: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》也有精辟的讲述。
……………………………………………………………………………………………………………… ……………………………………………………………………………………………………………… 我在其中一个SESSION 执行 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> …………………………………………………………………………………………………………………… …………………………………………………………………………………………………………………… 开多少个parallel server也要看当时系统的负载,并行是很耗系统资源的, 这个并行度和你初始化参数有关。CPU_COUNT 、PARALLEL_THREADS_PER_CPU 等等都有关系。如果你建表的时候没有明确指定并行度,那么oracle会自动的根据需要设定并行度。 相关资源:Java 面经手册·小傅哥(公众号:bugstack虫洞栈).pdf