oracle使用并行踩过的坑

1、并行机制的简述sql

并行处理的机制实际上就是把一个要扫描的数据集分红不少小数据集,Oracle会根据初始化参数 PARALLEL_MIN_SERVERS=n的值启动几个并行服务进程同时处理这些小数据集,最后将这些结果汇总,做为最终的处理结果返回给用户。session


2、并行使用场景oracle

一、Parallel query(并行查询)ide

执行并行查询是须要符合如下条件:性能

ASQL语句中有Hint提示,好比Parallel或者 Parallel_index测试

BSQL语句中引用的对象被设置了并行属性。this

C、多表关联中,至少有一个表执行全表扫描(Fulltable scan)或者跨分区的Index range SCANspa

 

二、Parallel DDL(并行DDL操做,如建表,建索引等)设计

 如:createtable xx parallel 4 as select * from xxx;orm

          create index xxx on tab_xx(column) parallel 4;

 

三、Parallel DML(并行DML操做,如insert、update、delete等)

 如:insert/*+parallel(t 2) */ into t select /*+parallel(t1 2) */ * from t1;

 

下面从以上三个场景各举一例来讲一下并行易踩的坑。

 

3、并行对执行计划的影响

某日,开发忽然找过来:喂、DBA吗?有个测试环境的SQL执行计划和生产环境不同,严重影响测试进度。记得当时差很少是这样的,对方向我扔了一条执行计划有问题的SQL,而后不说话。做为一个菜鸟,赶忙把生产执行计划和测试环境对比了一下,发现果然不同,折腾了很久,才发现该SQL中的某个表并行度为8,致使了执行计划异常。记得该表是TB级的大小,是个多表管理的查询语句,并行度为8以后走了全表扫描(Full table scan),能够想象是又多慢。由于是测试环境,谁作什么操做以后没有关闭并行就不深究了。下面看一下oracle联机文档:http://download.oracle.com/docs/cd/E11882_01/server.112/e10821/ex_plan.htm#PFGRF94687对并行处理的执行计划的解读。

SQL>createtable emp2 as select * from scott.emp;
 
SQL>altertable emp2 parallel 2;  --能够查看dba_tables表degree列
 
SQL>explainplan for select sum(sal) from emp2 group by deptno;
 
SQL> select * fromtable(dbms_xplan.display());
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3939201228
 
------------------------------------------------------------------------------------------------------------------
| Id | Operation              |Name     | Rows  | Bytes | Cost (%CPU)| Time     |        TQ  |IN-OUT| PQ Distrib |
------------------------------------------------------------------------------------------------------------------
|   0| SELECT STATEMENT    |         |         1|          26 |           2   (0)| 00:00:01 |          |         |                  |
|   1|  PX COORDINATOR           |         |          |           |                 |        |            |         |                 |
|   2|   PX SEND QC (RANDOM)          | :TQ10001 |  1 |          26 |           2  (0)| 00:00:01 |  Q1,01 | P->S |QC (RAND)  |
|   3|    HASH GROUP BY |         |         1 |         26 |           2  (0)| 00:00:01 |  Q1,01 | PCWP |                  |
|   4|     PX RECEIVE                  |         |         1 |         26 |           2  (0)| 00:00:01 |  Q1,01 | PCWP |                  |
|   5|      PX SEND HASH          | :TQ10000 |  1 |          26 |           2  (0)| 00:00:01 |  Q1,00 | P->P |HASH          |
|   6|       HASH GROUP BY    |         |         1 |         26 |           2  (0)| 00:00:01 |  Q1,00 | PCWP |                  |
|   7|        PX BLOCK ITERATOR |             |         1 |         26 |           2  (0)| 00:00:01 |  Q1,00 | PCWC |                  |
|   8|   TABLE ACCESS FULL| EMP2     |  1 |         26 |           2  (0)| 00:00:01 |  Q1,00 | PCWP |                  |
------------------------------------------------------------------------------------------------------------------
 
Note
-----
   -dynamic sampling used for this statement (level=2)
 
19 rows selected.

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

Parallel to SerialP->S: 表示一个并行操做发送数据给一个串行操做,一般是并行incheng将数据发送给并行调度进程。

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

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

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

Serial to ParallelS->P: 一个串行操做发送数据给并行操做,若是select 部分是串行操做,就会出现这个状况。


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

 

4、并行建主键惟一性索引的影响

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

一、开并行重建惟一索引:

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

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

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

 

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


5、并行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

 

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

 

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

相关文章
相关标签/搜索