☞ 병렬 처리란?
\- 그림7-1 참조
1. 병렬 SQL이 시작되면 QC는 사용자가 지정한 PARALLEL 개수와 오퍼레이션 종류에 따라 하나 또는 두 개의 병렬 서버 집합을 할당.
그리고 서버 풀(parallel_min_servers 파라미터로 설정된 만큼의 병렬 프로세스를 오라클이 기본적으로 생성해 서버 풀에 담아 둠)로부터
필요한 만큼 서버 프로세스를 확보하고, 부족분은 새로 생성함
2. QC는 각 병렬 서버에게 작업을 할당하고 관리 감독한다.
3. 병렬로 처리하도록 사용자가 지시하지 않은 테이블은 QC가 직접 처리함.
아래의 실행계획에서 DEPT 테이블을 직렬로 읽어 병렬 서버에 전송하는 8~9번 오퍼레이션은 QC 몫
4. QC는 각 병렬 서버로부터의 산출물을 통합하는 작업을 수행함.
아래의 실행계획에서, 집계 함수를 수행할 때 각 병렬 서버가 자신의 처리 범위 내에서 집계(4번)한 값을 QC에게 전송(3번)하면, QC가 최종 집계(1번)을 한다.
5. QC는 쿼리의 최종 결과집합을 사용자에게 전송하며, DML일 경우 갱신 건수를 집계해서 전송. 전송 단계에서는 스칼라 서브쿼리도 QC가 수행함.
-- 오라클 버전
SELECT * FROM v$version
;
BANNER
------------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit
PL/SQL Release 10.2.0.3.0 - Production
-- EMP, DEPT 테이블 생성
CREATE TABLE EMP
(EMPNO NUMBER(4) NOT NULL,
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(7, 2),
COMM NUMBER(7, 2),
DEPTNO NUMBER(2));
INSERT INTO EMP VALUES
(7369, 'SMITH', 'CLERK', 7902,
TO_DATE('17-DEC-1980', 'DD-MON-YYYY'), 800, NULL, 20);
INSERT INTO EMP VALUES
(7499, 'ALLEN', 'SALESMAN', 7698,
TO_DATE('20-FEB-1981', 'DD-MON-YYYY'), 1600, 300, 30);
INSERT INTO EMP VALUES
(7521, 'WARD', 'SALESMAN', 7698,
TO_DATE('22-FEB-1981', 'DD-MON-YYYY'), 1250, 500, 30);
INSERT INTO EMP VALUES
(7566, 'JONES', 'MANAGER', 7839,
TO_DATE('2-APR-1981', 'DD-MON-YYYY'), 2975, NULL, 20);
INSERT INTO EMP VALUES
(7654, 'MARTIN', 'SALESMAN', 7698,
TO_DATE('28-SEP-1981', 'DD-MON-YYYY'), 1250, 1400, 30);
INSERT INTO EMP VALUES
(7698, 'BLAKE', 'MANAGER', 7839,
TO_DATE('1-MAY-1981', 'DD-MON-YYYY'), 2850, NULL, 30);
INSERT INTO EMP VALUES
(7782, 'CLARK', 'MANAGER', 7839,
TO_DATE('9-JUN-1981', 'DD-MON-YYYY'), 2450, NULL, 10);
INSERT INTO EMP VALUES
(7788, 'SCOTT', 'ANALYST', 7566,
TO_DATE('09-DEC-1982', 'DD-MON-YYYY'), 3000, NULL, 20);
INSERT INTO EMP VALUES
(7839, 'KING', 'PRESIDENT', NULL,
TO_DATE('17-NOV-1981', 'DD-MON-YYYY'), 5000, NULL, 10);
INSERT INTO EMP VALUES
(7844, 'TURNER', 'SALESMAN', 7698,
TO_DATE('8-SEP-1981', 'DD-MON-YYYY'), 1500, 0, 30);
INSERT INTO EMP VALUES
(7876, 'ADAMS', 'CLERK', 7788,
TO_DATE('12-JAN-1983', 'DD-MON-YYYY'), 1100, NULL, 20);
INSERT INTO EMP VALUES
(7900, 'JAMES', 'CLERK', 7698,
TO_DATE('3-DEC-1981', 'DD-MON-YYYY'), 950, NULL, 30);
INSERT INTO EMP VALUES
(7902, 'FORD', 'ANALYST', 7566,
TO_DATE('3-DEC-1981', 'DD-MON-YYYY'), 3000, NULL, 20);
INSERT INTO EMP VALUES
(7934, 'MILLER', 'CLERK', 7782,
TO_DATE('23-JAN-1982', 'DD-MON-YYYY'), 1300, NULL, 10);
CREATE TABLE DEPT
(DEPTNO NUMBER(2),
DNAME VARCHAR2(14),
LOC VARCHAR2(13) );
INSERT INTO DEPT VALUES (10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO DEPT VALUES (20, 'RESEARCH', 'DALLAS');
INSERT INTO DEPT VALUES (30, 'SALES', 'CHICAGO');
INSERT INTO DEPT VALUES (40, 'OPERATIONS', 'BOSTON');
COMMIT;
/
CREATE UNIQUE INDEX EMP_U1 ON EMP (EMPNO);
CREATE INDEX EMP_N1 ON EMP (DEPTNO);
CREATE UNIQUE INDEX DEPT_U1 ON DEPT (DEPTNO);
CREATE INDEX DEPT_N1 ON DEPT (LOC);
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(USER,
'EMP',
CASCADE => TRUE);
END;
/
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(USER,
'DEPT',
CASCADE => TRUE);
END;
/
-- 테스트
EXPLAIN PLAN FOR
SELECT /*+ ORDERED USE_HASH(D) FULL(D) FULL(E) NOPARALLEL(D) PARALLEL(E 4) */
COUNT(*),
MIN(E.SAL),
MAX(E.SAL),
AVG(E.SAL),
SUM(E.SAL)
FROM DEPT D,
EMP E
WHERE D.LOC = 'CHICAGO'
AND E.DEPTNO = D.DEPTNO
;
@xplan
-------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
-------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 18 | 8 (13)| 00:00:01 | | | |
| 1 | SORT AGGREGATE | | 1 | 18 | | | | | |
| 2 | PX COORDINATOR | | | | | | | | |
| 3 | PX SEND QC (RANDOM) | :TQ10002 | 1 | 18 | | | Q1,02 | P->S | QC (RAND) |
| 4 | SORT AGGREGATE | | 1 | 18 | | | Q1,02 | PCWP | |
|* 5 | HASH JOIN | | 14 | 252 | 8 (13)| 00:00:01 | Q1,02 | PCWP | |
| 6 | BUFFER SORT | | | | | | Q1,02 | PCWC | |
| 7 | PX RECEIVE | | 2 | 22 | 5 (0)| 00:00:01 | Q1,02 | PCWP | |
| 8 | PX SEND HASH | :TQ10000 | 2 | 22 | 5 (0)| 00:00:01 | | S->P | HASH |
|* 9 | TABLE ACCESS FULL| DEPT | 2 | 22 | 5 (0)| 00:00:01 | | | |
| 10 | PX RECEIVE | | 28 | 196 | 2 (0)| 00:00:01 | Q1,02 | PCWP | |
| 11 | PX SEND HASH | :TQ10001 | 28 | 196 | 2 (0)| 00:00:01 | Q1,01 | P->P | HASH |
| 12 | PX BLOCK ITERATOR | | 28 | 196 | 2 (0)| 00:00:01 | Q1,01 | PCWC | |
| 13 | TABLE ACCESS FULL| EMP | 28 | 196 | 2 (0)| 00:00:01 | Q1,01 | PCWP | |
-------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("E"."DEPTNO"="D"."DEPTNO")
9 - filter("D"."LOC"='CHICAGO')
26 rows selected.
;
-- QC를 보기위한 작업
-- EMP 테이블 복제한 테이블 생성
CREATE TABLE T_EMP AS
SELECT *
FROM EMP,
(SELECT ROWNUM NO
FROM DUAL
CONNECT BY LEVEL <= 100000);
-- SESSION_1 수행
SELECT /*+ ORDERED USE_HASH(D) FULL(D) FULL(E) NOPARALLEL(D) PARALLEL(E 4) */
COUNT(*),
MIN(E.SAL),
MAX(E.SAL),
AVG(E.SAL),
SUM(E.SAL)
FROM DEPT D,
T_EMP E
WHERE D.LOC = 'CHICAGO'
AND E.DEPTNO = D.DEPTNO
;
-- SESSION_2에서 모니터링
SELECT LPAD(NVL(TO_CHAR(PS.SERVER#), 'Main'), 5, ' ') CLASS,
PS.SID || ', ' || PS.SERIAL# AS SID_SERIAL,
PS.QCSID,
PS.DEGREE,
SUBSTR(S.STATUS, 1, 1) AS STATUS,
P.SPID SPID,
DECODE(SUBSTR(S.ACTION, 1, 4),
'FRM:',
SUBSTR(S.MODULE, 1, 15) || '(Form)',
'Onli',
SUBSTR(S.MODULE, 1, 15) || '(Form)',
'Conc',
SUBSTR(S.MODULE, 1, 15) || '(Conc)',
SUBSTR(S.MODULE, 1, 20)) AS MODULE,
SUBSTR(S.PROGRAM, -6, 6) PROGRAM,
SUBSTR(SW.EVENT, 1, 30) WAIT,
LAST_CALL_ET LAST_CALL_ET,
(SELECT SUBSTR(SQL_TEXT, 1, 50)
FROM V$SQL SQ
WHERE SQ.ADDRESS = S.SQL_ADDRESS
AND SQ.HASH_VALUE = S.SQL_HASH_VALUE
AND ROWNUM = 1) SQL_TEXT,
NVL(PS.SERVER#, 0) AS SERVER_NUM
FROM V$SESSION S,
V$PROCESS P,
V$SESSION_WAIT SW,
V$PX_SESSION PS
WHERE S.PADDR = P.ADDR
AND SW.SID = S.SID
AND S.SID = PS.SID
AND S.SERIAL# = PS.SERIAL#
AND NOT EXISTS (SELECT 1
FROM V$BGPROCESS BP
WHERE P.ADDR = BP.PADDR)
ORDER BY PS.QCSID,
DEGREE NULLS FIRST,
SUBSTR(S.PROGRAM, -6, 6) NULLS FIRST,
CLASS
;
CLASS SID,Serial# QCSID DEGREE S SPID MODULE PROGRAM WAIT LCE SQL_TEXT SERVER_NUM
----- ------------ ------ ------ - -------- -------- -------- --------------------- --- -------------------------------------------------- ----------
Main 9851, 75 9851 A 376910 SQL*Plus sw.exe PX Deq: Execute Reply 0 SELECT /*+ ORDERED USE_HASH(D) FULL(D) FULL(E) NOP 0 <-- QC
1 9875, 102 9851 4 A 418678 SQL*Plus (P000) direct path read 0 SELECT /*+ ORDERED USE_HASH(D) FULL(D) FULL(E) NOP 1 <-- SP-1
2 9766, 11 9851 4 A 180228 SQL*Plus (P001) direct path read 0 SELECT /*+ ORDERED USE_HASH(D) FULL(D) FULL(E) NOP 2 <-- SP-2
3 9754, 199 9851 4 A 438880 SQL*Plus (P002) direct path read 0 SELECT /*+ ORDERED USE_HASH(D) FULL(D) FULL(E) NOP 3 <-- SP-3
4 9758, 91 9851 4 A 475718 SQL*Plus (P003) direct path read 0 SELECT /*+ ORDERED USE_HASH(D) FULL(D) FULL(E) NOP 4 <-- SP-4
SELECT /*+ FULL(고객) PARALLEL(고객 4) */
*
FROM 고객
ORDER BY 고객명
;
\- 그림 7_2 참조
1. 이해를 돕기 위해, 8명의 영업사원이 각자 관리하던 명함을 영업팀에서 통합 관리할 목적으로 명함 전체를 이름순으로 정렬하는 경우,
두 가지 방법을 생각해 볼 수 있음.
첫번째 방법은, 8명 각자 자신의 것을 정렬하고 이를 영업팀장이 최종적으로 Merge하는 방법이 있다.
두번째는, 2개조로 나누고 역할을 분담해 서로 다른 작업을 동새에 진행하는 것인데, 영업팀장은 관리를(QC) 하고,
4명은 분배, 4명은 분배된 내용을 정렬하는 방법이다.
2. 정렬팀은 먼저 알파벳 순으로 1/4 배분을 받고, 분배팀은 QC로부터 할당받은 뭉치를 정렬팀에게 보내서, 결과적으로 정렬팀이
자신의 분배범위 내에서만 정렬하고, 최종적으로 이 4개만 MERGE하면 된다.
3. 첫 번째 방법은 작업자가 많을수록 최종 QC가 머지하는 단계에서 부하가 걸리므로, 오라클은 ORDER BY일 경우 두 번째 방식을
사용한다.
4. 이때, 이렇게 동시에 처리하는 것을 'Intra-Operation Parallelism'이라고 하고, 작업을 다른조에 분배하거나 QC에게 전송하는
작업을 동시에 처리하는 것을 'Inter-Operation Parallelism'라고 함.
차이점은 'Intra-Operation Parallelism'은 프로세스간 통신이 필요 없고, 'Inter-Operation Parallelism'은 프로세스간 통신이 필요함.
\- 그림 7_3 참조
EXPLAIN PLAN FOR
SELECT /*+ ORDERED USE_HASH(D) FULL(D) FULL(E) NOPARALLEL(D) PARALLEL(E 2) PQ_DISTRIBUTE(E BROADCAST NONE) */
*
FROM DEPT D,
EMP E
WHERE E.DEPTNO = D.DEPTNO
ORDER BY E.ENAME
;
@xplan
--------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
--------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 798 | 9 (12)| 00:00:01 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (ORDER) | :TQ10002 | 14 | 798 | 9 (12)| 00:00:01 | Q1,02 | P->S | QC (ORDER) |
| 3 | SORT ORDER BY | | 14 | 798 | 9 (12)| 00:00:01 | Q1,02 | PCWP | |
| 4 | PX RECEIVE | | 14 | 798 | 8 (0)| 00:00:01 | Q1,02 | PCWP | |
| 5 | PX SEND RANGE | :TQ10001 | 14 | 798 | 8 (0)| 00:00:01 | Q1,01 | P->P | RANGE |
|* 6 | HASH JOIN | | 14 | 798 | 8 (0)| 00:00:01 | Q1,01 | PCWP | |
| 7 | BUFFER SORT | | | | | | Q1,01 | PCWC | |
| 8 | PX RECEIVE | | 4 | 80 | 5 (0)| 00:00:01 | Q1,01 | PCWP | |
| 9 | PX SEND BROADCAST | :TQ10000 | 4 | 80 | 5 (0)| 00:00:01 | | S->P | BROADCAST |
| 10 | TABLE ACCESS FULL| DEPT | 4 | 80 | 5 (0)| 00:00:01 | | | |
| 11 | PX BLOCK ITERATOR | | 14 | 518 | 3 (0)| 00:00:01 | Q1,01 | PCWC | |
| 12 | TABLE ACCESS FULL | EMP | 14 | 518 | 3 (0)| 00:00:01 | Q1,01 | PCWP | |
--------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
6 - access("E"."DEPTNO"="D"."DEPTNO")
24 rows selected.
1. Id 9~10
- QC가 DEPT 테이블을 읽어 첫 번째 서버집합(Q1, 01)에게 전송
2. Id 5~12
- 첫 번째 서버집합(Q1,01)은 EMP 테이블을 병렬로 읽으면서 앞서 QC에게서 받은 DEPT 테이블과 조인
- 조인에 성공한 레코드는 바로바로 두 번째 서버집합(Q1, 02)에게 전송
3. Id 2~12
- 마지막으로, 두 번째 서버집합(Q1, 02)은 전송받은 레코드를 정렬하고 나서 QC에게 전송
NAME | DESCRIPTION | 설명 |
---|---|---|
S->P | PARALLEL_FROM_SERIAL | ☞ QC가 읽은 데이터를 테이블 큐를 통해 병렬 서버 프로세스에게 전송 |
P->S | PARALLEL_TO_SERIAL | ☞ 각 병렬 서버 프로세스가 처리한 데이터틀 QC에게 전송 ☞ 병렬 프로세스로부터 QC로 통신이 발생하므로 Inter-Operation Parallelism에 속함 (그러나 S->P는 통신을 하지만 병렬 오퍼레이션이 아니므로 Inter-Operation Parallelism이 아님) ☞ 'PQ Disrib' 항목에 있는 'QC(ORDER)' 의미는 ORDER BY가 사용되어 첫 번째 병렬 프로세스로부터 마지막 병렬 프로세스까지 순서대로 진행함을 의미 (만약 ORDER BY가 없다면 'QC(RAND)'가 나옴) |
P->P | PARALLEL_FROM_PARALLEL | ☞ 해당 오퍼레이션을 두 개의 서버집합이 처리함을 의미 ☞ 두 개의 서버집합간 통신이 발생하므로 Inter-Operation Parallelism에 속함 |
PCWP | PARALLEL_COMBINE_WITH_PARENT | ☞ 한 서버집합이 현재 스텝과 그 부모(Parent) 스텝을 모두 처리함을 의미 ☞ 병렬 오퍼리에션이긴 하지만 한 서버 집합 내에서는 프로세스 간 통신이 발생하지 않으므로 Intra-Operation Parallelism에 속함. |
PCWC | PARALLEL_COMBINE_WITH_CHILD | ☞ 한 서버집합이 현재 스텝과 그 자식(Child) 스텝을 모두 처리함을 의미 ☞ 병렬 오퍼리에션이긴 하지만 한 서버 집합 내에서는 프로세스 간 통신이 발생하지 않으므로 Intra-Operation Parallelism에 속함. |
NAME | 설명 |
---|---|
RANGE | ☞ ORDER BY 또는 GROUP BY를 병렬로 처리할 때 사용됨. ☞ 정렬 작업을 맡은 두 번째 서버 집합의 프로세스마다 처리범위를 지정하고 나서, 데이터를 읽는 첫 번째 서버 집합이 두 번째 서버 집합의 정해진 프로세스에게 "정렬된 키 값에 따라" 분배하는 방식 ☞ QC는 각 서버 프로세스에게 작업 범위를 할당하고 정렬 작업에는 직접 참여하지 않으며, 정렬이 완료되면 순서대로 결과를 받아서 사용자에게 전송하는 역할만 진행 |
HASH | ☞ 조인이나 HASH GROUP BY를 병렬로 처리할 때 사용. |
BROADCASE | ☞ QC 또는 첫 번째 서버 집합에 속한 프로세스들이 각각 읽은 데이터를 두 번째 서버 집합에 속한 "모든" 병렬 프로세스에게 전송하는 방식 |
KEY | ☞ 특정 컬럼 기준으로 테이블 또는 인덱스를 파티셔닝할 때 사용하는 분배 방식 |
ROUND-ROBIN | ☞ 파티션 키, 정렬 키, 해시 함수 등에 의존하지 않고 반대편 병렬 서버에 무작위로 데이터를 분배하는 방식. |
☞ 데이터를 병렬로 처리할 때 일의 최소 단위를 'Granule'이라고 하며, 병ㅕㄹ 서버는 한 번에 하나의 Granule씩만 처리
☞ Granule 개수와 크기는 병렬도와 관계가 있으며, 이는 병렬 서버 사이에 일을 고르게 분배하는데 큰 영향을 줌
| 11 | PX BLOCK ITERATOR | | 14 | 518 | 3 (0)| 00:00:01 | Q1,01 | PCWC | |
| 12 | TABLE ACCESS FULL | EMP | 14 | 518 | 3 (0)| 00:00:01 | Q1,01 | PCWP | |
Partition-Wise 조인 |
파티션 인덱스를 병렬로 스캔할 때 |
파티션 인덱스를 병렬로 갱신할 때 |
9iR1 이전에서의 병렬 DML |
파티션 테이블 또는 파티션 인덱스를 병렬로 생성할 때 |
| 4 | PX RECEIVE | | 14 | 126 | 3 (0)| 00:00:01 | | | Q1,01 | PCWP | |
| 5 | PX SEND PARTITION (KEY) | :TQ10000 | 14 | 126 | 3 (0)| 00:00:01 | | | Q1,00 | P->P | PART (KEY) |
| 6 | PX PARTITION RANGE ITERATOR | | 14 | 126 | 3 (0)| 00:00:01 | | | Q1,00 | PCWC | |
| 7 | TABLE ACCESS FULL | EMP | 14 | 126 | 3 (0)| 00:00:01 | | | Q1,00 | PCWP | |
☞ 병렬 처리 과정에서 자주 발생하는 대기 이벤트 요약
이벤트명 | 클래스 | 설명 |
---|---|---|
PX Deq: Execute Reply | Idle | ☞ QC가 각 병렬 서버에게 작업을 배분하고서 작업이 완료되기를 기다리는 상태 |
PX Deq: Execute Msg | Idle | ☞ 병렬 서버가 자신의 임무를 완수하고서 다른 병렬 서버가 일을 마치기를 기다리는 상태. ☞ QC 또는 소비자 병렬 서버에게 데이터 전송을 완료했을 때 나타남. |
PX Deq: Table Q Normal | Idle | ☞ 메세지 수신 대기. 메세지 큐에 데이터가 쌓이기를 기다리는 상태. |
PX Deq Credit: send blkd | Other | ☞ 메세지 송신 대기. ☞ QC 또는 소비자 병렬 서버에게 전송할 데이터가 있는데 블로킹 된 상태. ☞ 생산자 프로세스가 메세지 큐를 통해 데이터를 전송하려고 하는데 어떤 이유에서건 소비자 프로세스가 버퍼에서 데이터를 빨리 꺼내가지 않을 때 발생. |
PX Deq Credit: need bulffer | Idle | ☞ 데이터를 전송하기 전에 상대편 병렬 서버 또는 QC로부터 credit 비트를 얻으려고 대기하는 상태. ☞ 오라클 측의 설명(메타링크 문서번호 271767.1)에 의하면 'PX Deq Credit:send blkd'와 'PX Deq Credit: need bulffer'는 거의 같은 대기 이벤트이고, 내부적인 이유로 전자는 로컬 시스템에서 자주 발생하며, 후자는 RAC 시스템에서 자주 발생함. |
-- SESSION_1 수행
SELECT /*+ ORDERED USE_HASH(D) FULL(D) FULL(E) NOPARALLEL(D) PARALLEL(E 4) */
COUNT(*),
MIN(E.SAL),
MAX(E.SAL),
AVG(E.SAL),
SUM(E.SAL)
FROM DEPT D,
T_EMP E
WHERE D.LOC = 'CHICAGO'
AND E.DEPTNO = D.DEPTNO
;
-- SESSION_2 수행
SELECT DECODE(A.QCSERIAL#, NULL, 'PAREMT', 'CHILD') ST_LVL,
A.SERVER_SET "SET",
A.SID,
A.SERIAL#,
STATUS,
EVENT,
WAIT_CLASS
FROM V$PX_SESSION A,
V$SESSION B
WHERE A.SID = B.SID
AND A.SERIAL# = B.SERIAL#
ORDER BY A.QCSID,
ST_LVL DESC,
A.SERVER_GROUP,
A.SERVER_SET
;
ST_LVL SET SID SERIAL# STATUS EVENT WAIT_CLASS
------ --- ---- ------- -------- --------------------- ----------
PAREMT 7634 6110 ACTIVE PX Deq: Execute Reply Idle
CHILD 1 7647 574 ACTIVE direct path read User I/O
CHILD 1 7860 1083 ACTIVE direct path read User I/O
CHILD 1 7933 11436 ACTIVE direct path read User I/O
CHILD 1 7938 4284 ACTIVE direct path read User I/O
CHILD 1 7872 2783 INACTIVE PX Deq: Execution Msg Idle
CHILD 1 7801 2574 INACTIVE PX Deq: Execution Msg Idle