oracle加并行好不好,深入理解Oracle的并行操作

并行(Parallel)和OLAP系统

并行的实现机制是:首先,Oracle会创建一个进程用于协调并行服务进程之间的信息传递,这个协调进程将需要操作的数据集(比如表的数据块)分割成很多部分,称为并行处理单元,然后并行协调进程给每个并行进程分配一个数据单元。比如有四个并行服务进程,他们就会同时处理各自分配的单元,当一个并行服务进程处理完毕后,协调进程就会给它们分配另外的单元,如此反复,直到表上的数据都处理完毕,最后协调进程负责将每个小的集合合并为一个大集合作为最终的执行结果,返回给用户。

并行处理的机制实际上就是把一个要扫描的数据集分成很多小数据集,Oracle会启动几个并行服务进程同时处理这些小数据集,最后将这些结果汇总,作为最终的处理结果返回给用户。

这种数据并行处理方式在OLAP系统中非常有用,OLAP系统的表通常来说都是非常大,如果系统的CPU比较多,让所有的CPU共同来处理这些数据,效果就会比串行执行要高得多。

然而对于OLTP系统,通常来讲,并行并不合适,原因是OLTP系统上几乎在所有的SQL操作中,数据访问路径基本上以索引访问为主,并且返回结果集非常小,这样的SQL操作的处理速度一般非常快,不需要启用并行。

并行处理的机制

当Oracle数据库启动的时候,实例会根据初始化参数 PARALLEL_MIN_SERVERS=n的值来预先分配n个并行服务进程,当一条SQL被CBO判断为需要并行执行时发出SQL的会话进程变成并行协助进程,它按照并行执行度的值来分配进程服务器进程。

首先协调进程会使用ORACLE启动时根据参数: parallel_min_servers=n的值启动相应的并行服务进程,如果启动的并行服务器进程数不足以满足并行度要求的并行服务进程数,则并行协调进程将额外启动并行服务进程以提供更多的并行服务进程来满足执行的需求。然后并行协调进程将要处理的对象划分成小数据片,分给并行服务进程处理;并行服务进程处理完毕后将结果发送给并行协调进程,然后由并行协调进程将处理结果汇总并发送给用户。

刚才讲述的是一个并行处理的基本流程。实际上,在一个并行执行的过程中,还存在着并行服务进程之间的通信问题。

在一个并行服务进程需要做两件事情的时候,它会再启用一个进程来配合当前的进程完成一个工作,比如这样的一条SQL语句:

Select * from employees order by last_name;

假设employees表中last_name列上没有索引,并且并行度为4,此时并行协调进程会分配4个并行服务进程对表employees进行全表扫描操作,因为需要对结果集进行排序,所以并行协调进程会额外启用4个并行服务进程,用于处理4个进程传送过来的数据,这新启用的用户处理传递过来数据的进程称为父进程,用户传出数据(最初的4个并行服务进程)称为子进程,这样整个并行处理过程就启用了8个并行服务进程。 其中每个单独的并行服务进程的行为叫作并行的内部操作,而并行服务进程之间的数据交流叫做并行的交互操作。

这也是有时我们发现并行服务进程数量是并行度的2倍,就是因为启动了并行服务父进程操作的缘故。

读懂一个并行处理的执行计划

CREATE TABLE emp2 AS SELECT * FROM employees;

ALTER TABLE emp2 PARALLEL 2;

EXPLAIN PLAN FOR SELECT SUM(salary) FROM emp2 GROUP BY department_id;

SQL> select * from table(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         |          |   107 |  2782 |     3  (34)| 00:00:01 |        |      |            |

|   1 |  PX COORDINATOR          |          |       |       |            |          |        |      |            |

|   2 |   PX SEND QC (RANDOM)    | :TQ10001 |   107 |  2782 |     3  (34)| 00:00:01 |  Q1,01 | P->S | QC (RAND)  |

|   3 |    HASH GROUP BY         |          |   107 |  2782 |     3  (34)| 00:00:01 |  Q1,01 | PCWP |            |

|   4 |     PX RECEIVE           |          |   107 |  2782 |     3  (34)| 00:00:01 |  Q1,01 | PCWP |            |

|   5 |      PX SEND HASH        | :TQ10000 |   107 |  2782 |     3  (34)| 00:00:01 |  Q1,00 | P->P | HASH       |

|   6 |       HASH GROUP BY      |          |   107 |  2782 |     3  (34)| 00:00:01 |  Q1,00 | PCWP |            |

|   7 |        PX BLOCK ITERATOR |          |   107 |  2782 |     2   (0)| 00:00:01 |  Q1,00 | PCWC |            |

|   8 |         TABLE ACCESS FULL| EMP2     |   107 |  2782 |     2   (0)| 00:00:01 |  Q1,00 | PCWP |            |

------------------------------------------------------------------------------------------------------------------

Note

-----

- dynamic sampling used for this statement

19 rows selected.

通过执行计划,我们来看一下它的执行步骤:

1、并行服务进程对EMP2表进行全表扫描。

2、并行服务进程以ITERATOR(迭代)方式访问数据块,也就是并行协调进程分给每个并行服务进程一个数据片,在这个数据片上,并行服务进程顺序地访问每个数据块(Iterator),所有的并行服务进程将扫描的数据块传给另一组并行服务进程(父进程)用于做Hash Group操作。

3、并行服务父进程对子进程传递过来的数据做Hash Group操作。

4、并行服务进程(子进程)将处理完的数据发送出去。

5、并行服务进程(父进程)接收到处理过的数据。

6、合并处理过的数据,按照随机的顺序发给并行协调进程(QC:Query Conordinator)。

7、并行协调进程将处理结果发给用户。

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

Parallel to Serial(P->S): 表示一个并行操作发送数据给一个串行操作

Parallel to Parallel(P->P):表示一个并行操作向另一个并行操作发送数据

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

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

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

并行执行等待事件

在做并行执行方面的性能优化的时候,可能会遇到如下等待事件

PX Deq Credit: send blkd

这是一个有并行环境的数据库中,从statspack 或者AWR中经常可以看到的等待事件。 在Oracle 9i 里面, 这个等待时间被列入空闲等待。

一般来说空闲等待可以忽略它,但是实际上空闲等待也是需要关注的,因为一个空闲的等待,它反映的是另外的资源已经超负荷运行了。基于这个原因,在Oracle 10g里已经把PX Deq Credit: send blkd等待时间不再视为空闲等待,而是列入了Others 等待事件范围。

PX Deq Credit: send blkd 等待事件的意思是:当并行服务进程向并行协调进程QC(也可能是上一层的并行服务进程)发送消息时,同一时间只有一个并行服务进程可以向上层进程发送消息,这时候如果有其他的并行服务进程也要发送消息,就只能等待了。直到获得一个发送消息的信用信息(Credit),这时候会触发这个等待事件,这个等待事件的超时时间为2秒钟。

如果我们启动了太多的并行进程,实际上系统资源(CPU)或者QC 无法即时处理并行服务发送的数据,那么等待将不可避免。 对于这种情况,我们就需要降低并行处理的并行度。

当出现PX Deq Credit:send blkd等待的时间很长时,我们可以通过平均等待时间来判断等待事件是不是下层的并行服务进程空闲造成的。该等待事件的超时时间是2秒,如果平均等待时间也差不多是2秒,就说明是下层的并行进程“无事所做”,处于空闲状态。 如果和2秒的差距很大,就说明不是下层并行服务超时导致的空闲等待,而是并行服务之间的竞争导致的,因为这个平均等待事件非常短,说明并行服务进程在很短时间的等待之后就可以获取资源来处理数据。

所以对于非下层的并行进程造成的等待,解决的方法就是降低每个并行执行的并行度,比如对象(表,索引)上预设的并行度或者查询Hint 指定的并行度。

并行执行的使用范围

Parallel Query( 并行查询 )

并行查询可以在查询语句,子查询语句中使用,但是不可以使用在一个远程引用的对象上(如DBLINK)。

一个查询能够并行执行,需要满足以下条件

1、SQL语句中有Hint提示,比如Parallel或者Parallel_index。

2、SQL语句中引用的对象被设置了并行属性。

3、多表关联中,至少有一个表执行全表扫描(Full table scan)或者跨分区的Index range SCAN。 如:

select /*+parallel(t 4)×/ * from t;

Parallel DDL(并行DDL操作,如建表,建索引等)

表的并行操作

CREATE TABLE table_name parallel 4 AS SELECT ....

ALTER TABLE table_name move partition partition_name parallel 4;

Alter table table_name split partition partition_name ...

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值