in-out字段的pcwc或是pcwp代表什么意思?
一、执行计划里的(单独型)操作一般都是子操作在父操作前面执行,表现在并行查询语句的执行计划里的in_out字段(执行计划里当发生并行查询时才会出现的字段)就是pcwp,即子操作在父操作前面执行,亦即在一个进程集(同一个进程集的各个进程同时用于执行同一种操作,故而称该操作为并行操作)同一个进程可以执行完一个操作后再执行其父操作(这里,子操作和父操作有个执行先后顺序)
例如,
EXPLAIN PLAN FOR
SELECT SUM(salary) FROM emp2 GROUP BY department_id;
SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY());
--------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU) | TQ |IN-OUT| PQ Distrib |
--------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 107 | 2782 | 3 (34) | | | |
| 1 | PX COORDINATOR | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10001 | 107 | 2782 | 3 (34) | Q1,01 | P->S | QC (RAND) |
| 3 | HASH GROUP BY | | 107 | 2782 | 3 (34) | Q1,01 | PCWP | |
| 4 | PX RECEIVE | | 107 | 2782 | 3 (34) | Q1,01 | PCWP | |
| 5 | PX SEND HASH | :TQ10000 | 107 | 2782 | 3 (34) | Q1,00 | P->P | HASH |
| 6 | HASH GROUP BY | | 107 | 2782 | 3 (34) | Q1,00 | PCWP | |
| 7 | PX BLOCK ITERATOR | | 107 | 2782 | 2 (0) | Q1,00 | PCWP | |
| 8 | TABLE ACCESS FULL| EMP2 | 107 | 2782 | 2 (0) | Q1,00 | PCWP | |
--------------------------------------------------------------------------------------------------------
从下往上,从右向左读时,先执行 TABLE ACCESS FULL,故而在其字段 IN-OUT为 PCWP,再 执行 PX BLOCK ITERATOR,故而在其字段IN-OUT为PCWP,最后,执行 HASH GROUP BY ,故而在其字段IN-OUT为PCWP。注释:
0、| 7 | PX BLOCK ITERATOR | | 107 | 2782 | 2 (0) | Q1,00 | PCWP | |
其实,这里应该为PCWC。该例子是从别人博文上转载的,估计是有误的。不过拿来当例子说明正好。
1、in-out字段的意思是in代表生产者,即作为生产者的进程向表队列里放入数据,out代表消费者,即作为消费者的进程向表队列里拿出数据。
2、同一个进程集的进程可以对应执行多个操作(操作指的是执行计划里显示的operation字段里的操作),比如,先执行操作A,再执行操作B。同一个进程集的各个进程的行为是一样的,就是说同是进程集P里的进程E和F,若E的行为是先执行操作A,再执行操作B,则F的行为也是先执行操作A,再执行操作B。即使F的行为的操作和E一样,但是先后顺序不一样,即先执行操作B,再执行操作A,那也是不一样的行为。
二、执行计划里的(单独型)操作若是父操作在子操作前面执行,则表现在并行查询语句的执行计划里的in_out字段(执行计划里当发生并行查询时才会出现的字段)就是pcwc,即父操作在子操作前面执行,亦即在一个进程集(同一个进程集的各个进程同时用于执行同一种操作,故而称该操作为并行操作)同一个进程可以执行完一个操作后再执行其子操作(这里,子操作和父操作有个执行先后顺序)。例如,
select /*+ parallel(t1 4) parallel(t2 4) */rownum, t1.idfrom t1, t2 where t1.id = t2.id;
------------------------------------------------------------------------------------------------------------------
| Id | Operation |Name | Rows | Bytes |Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 100 | 600 | 5(20)| 00:00:01 | | | |
| 1 | COUNT | | | | | | | | |
| 2 | PX COORDINATOR | | | | | | | | |
| 3 | PX SEND QC (RANDOM) |:TQ10002 | 100 |600 | 5 (20)| 00:00:01 | Q1,02 | P->S | QC (RAND) |
|* 4 | HASH JOIN BUFFERED | | 100 | 600 | 5(20)| 00:00:01 | Q1,02 | PCWP | |
| 5 | PX RECEIVE | | 100 | 300 | 2(0)|00:00:01 | Q1,02 | PCWP | |
| 6 | PX SEND HASH | :TQ10000 | 100 | 300 |2 (0)| 00:00:01 | Q1,00 | P->P |HASH |
| 7 | PX BLOCK ITERATOR | | 100 | 300 | 2(0)| 00:00:01 | Q1,00 | PCWC | |
| 8 | TABLE ACCESSFULL | T1 | 100 | 300 | 2(0)| 00:00:01 | Q1,00 | PCWP | |
| 9 | PX RECEIVE | | 100 | 300 | 2(0)|00:00:01 | Q1,02 | PCWP | |
| 10 | PX SEND HASH | :TQ10001 | 100 | 300| 2 (0)| 00:00:01 | Q1,01 | P->P | HASH |
| 11 |PX BLOCK ITERATOR | | 100 | 300 | 2 (0)| 00:00:01 | Q1,01 | PCWC | |
| 12 | TABLE ACCESS FULL| T2 | 100 | 300 | 2 (0)|00:00:01 | Q1,01 | PCWP ||
------------------------------------------------------------------------------------------------------------------
从下往上,从右向左读时,应先执行TABLE ACCESS FULL但是PX BLOCK ITERATOR的in_out字段里的值为PCWC,故而先执行PX BLOCK ITERATOR,再执行TABLE ACCESS FULL。执行好TABLE ACCESS FULL后,根据自己的in_out字段里的值为PCWP再去执行PX BLOCK ITERATOR,则发现PX BLOCK ITERATOR已经执行过,故而执行上上个操作。
注释:
1、PX BLOCK ITERATOR:这个操作通常处于并行管道(即并行操作)的第一步,BLOCK ITERATOR把表分隔成多个(区域)块,每个(区域)块由涉及的并行服务器进程(slave process)中的一个去处理。(换句话说,在协调者进程QC预先对作用于同一个表的各个进程分配好各个进程负责的表区域后,各个进程执行BLOCK ITERATOR就是找到并确认标记下协调者进程QC分配给他们的区域。)
一般地,BLOCK ITERATOR 和TABLE ACCESS FULL操作是成对出现的。
前者是父操作,后者是子操作。
前者的in_out字段里的值为PCWC,后者的in_out字段里的值为PCWP。也就是说,要先分割好区域后,各个进程才能在各自区域进行全表扫描。
2、除了按数据块分割表区域,即PX BLOCK ITERATOR外,还有一种方法来分割表区域:按表分区来分割表区域,即PX PARTION ITERATOR。
3、PX BLOCK ITERATOR操作,是到目前为止本人有见过的其in_out字段值为PCWC的一种操作。
三、当发生并行查询时,其执行计划里的(单独型)子操作和父操作间的执行顺序还有另一种情况(除了子操作在父操作前面执行和父操作在子操作前面执行这两种情况外),就是s->p或是p->p、p->s。
注释:
判断是否有操作间的并行,看执行计划里的in-out字段是否有出现s->p或是p->p、p->s,出现这些时name字段里总是会出现表队列的(TQ10002,其中1表示dfo_number((来自v$pq_tqstat的字段)),2表示tq_id(来自v$pq_tqstat的字段))。
总结:
并行操作间关系(执行计划中in-out部分,指明了操作中数据流的方向)
p-s:并行进程集发送数据给串行进程(例如,协调者进程QC就是单个进程,或说串行进程)。
p-p:(有2组slavesprocess时使用),一个并行操作将数据发送给另一个并行操作。
s-p:串行发送数据给并行,效率差(1.单一进程产生数据没有多个进程消费数据快,消费者花很多时间等数据而不是处理数据,2.串行执行操作和并