当前位置:Gxlcms > 数据库问题 > oracle使用并行踩过的坑

oracle使用并行踩过的坑

时间:2021-07-01 10:21:17 帮助过:8人阅读

 

当使用了并行执行,SQL的执行计划中就会多出一列:in-out。该列帮助我们理解数据流的执行方法。它的一些值的含义如下:

Parallel to Serial(P->S): 表示一个并行操作发送数据给一个串行操作,通常是并行incheng将数据发送给并行调度进程。

Parallel to Parallel(P->P):表示一个并行操作向另一个并行操作发送数据,疆场是两个从属进程之间的数据交流。

Parallel Combined with parent(PCWP): 同一个从属进程执行的并行操作,同时父操作也是并行的。

Parallel Combined with Child(PCWC): 同一个从属进程执行的并行操作,子操作也是并行的。

Serial to Parallel(S->P): 一个串行操作发送数据给并行操作,如果select 部分是串行操作,就会出现这个情况。

 

如果知道了这些含义,再去解析执行计划的执行步骤就很容易了。这里强调一下,在处理某些操作之后,对表或者索引等对象开启了并行的,一定要记得关闭,不然后果很严重。

 

四、并行建主键唯一性索引的影响

又是某日,开发欲在测试环境对某一大表建主键唯一性索引(前期未规划好),语句执行了很长时间,因为其它人还需调用该表,但长时间的锁表,造成了不可用,于是请求DBA帮助,我看了语句之后,给出建议建索引时加上并行并以nologing的方式,然后让开发自己再去执行,可不久后,开发又找过来说还是很慢,查看没有任何阻塞之后,决定好好看看是不是真的很慢。经过一番折腾,终于知道慢的原因了,建主键约束时不会用到并行。解决方案分两步走,先建唯一性约束,再加主键约束。如下:

1、开并行重建唯一索引:

create unique index schema.xxx onschema.table_name(column1,column2) parallel 16;

2、取消并行:alter indexschema.xxx noparallel;  --索引建完后,一定记得取消并行

3、建主键约束:alter tableschame.xxx add constraint xxx primary key(column1,column2); --主键建立并行是没有效果的

 

相关测试这里就不演示了,测试方法很简单,在建索引的过程中查询dba_tables表degree列就行了。这里需要强调的一点是对于表的设计规划,前期一定要做好。

 

五、并行DML无法生效

SQL> explain plan for insert/*+parallel(a,4) */ into emp2 a select * from emp;
 
Explained.
 
SQL> select * fromtable(dbms_xplan.display());
 
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------
Plan hash value: 3956160932
 
---------------------------------------------------------------------------------
| Id | Operation              | Name |Rows      | Bytes | Cost (%CPU)| Time  |
---------------------------------------------------------------------------------
|   0| INSERT STATEMENT    |     |    1 |    87 |     2  (0)| 00:00:01 |
|   1|  LOAD TABLE CONVENTIONAL | EMP2 ||       |           |              |
|   2|   TABLE ACCESS FULL        | EMP     |     1 |   87 |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------------
 
Note
-----
   -dynamic sampling used for this statement (level=2)
 
13 rows selected.
 

可以看到该DML语句在有HINT提示的情况下没有使用并行,那要怎样才能使它使用并行呢?很简单,只需要执行alter session enable parallel dml; 这里也可以想一下和之前的并行查询和并行DDL是不同的。

SQL> alter session enable parallel dml;
 
Session altered.
 
SQL> explain plan for insert/*+parallel(a,4) */ into emp2 a select * from emp;
 
Explained.
 
SQL> select * fromtable(dbms_xplan.display());
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 883381916
 
-----------------------------------------------------------------------------------------------------------------
| Id | Operation             | Name       |Rows  | Bytes | Cost (%CPU)| Time        |          TQ |IN-OUT| PQ Distrib |
-----------------------------------------------------------------------------------------------------------------
|   0| INSERT STATEMENT   |         |           1 |  87 |  2   (0)| 00:00:01 |          |          |                   |
|   1|  PX COORDINATOR          |          |             |             |                   |         |              |          |                   |
|   2|   PX SEND QC (RANDOM)         | :TQ10001 |     1 |  87 |   2  (0)| 00:00:01 |  Q1,01 | P->S |QC (RAND)|
|   3|    LOAD AS SELECT| EMP2        |             |             |                   |         |  Q1,01 | PCWP |             |
|   4|     PX RECEIVE                 |          |          1 |  87 |  2   (0)| 00:00:01 |  Q1,01 | PCWP |          |
|   5|      PX SEND ROUND-ROBIN| :TQ10000 |     1 |  87|   2  (0)| 00:00:01 |           | S->P | RND-ROBIN         |
|   6|       TABLE ACCESS FULL | EMP       |           1 |  87|   2  (0)| 00:00:01 |           |          |                   |
-----------------------------------------------------------------------------------------------------------------
 
Note
-----
   -dynamic sampling used for this statement (level=2)
 
17 rows selected.
 

执行之后很见效,从执行计划重可以很清楚的看到该DML语句利用了并行度。这里使用的的hint的方式提示语句使用并行,若表本身设置了并行度呢?这种情况也是一样的,需要香执行alter session enable parallel dml; DML语句才可以使用到并行。

 

还有一个情况需要注意的是,对于开启并行度之后的表存在事务未提交的,后续的事务一定会失败,报如下错误:ORA-12838: cannot read/modify an object after modifying it inparallel。

SQL> alter table emp2 parallel 2;
 
Table altered.
 
SQL> alter session enable parallel dml;
 
Session altered.
 
SQL> insert into emp2 a select * fromemp;
 
0 rows created.
 
SQL> insert into emp2 a select * fromemp;
insert into emp2 a select * from emp
           *
ERROR at line 1:
ORA-12838: cannot read/modify an objectafter modifying it in parallel
 

 

该问题在写存储过程的时候一定要注意,事务及时提交,但这里又涉及到一个性能问题了,所以对于表这些对象的并行度尽量不要开启。

 

总结:并行确实能带来性能上的提升,效率的提高等,但是凡事都有两面性,滥用并行的话会导致程序争议用,资源过度的消耗,并行是会产生排序的,所以了解清除并行的本质,闲时使用并行,合理规划。

 

oracle使用并行踩过的坑

标签:const   scan   constrain   导致   关联   get   sch   bms   方式   

人气教程排行