Parallel 9i VS 10g
-- PARALLEL SQL CHECK
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 ;
인스턴스내 병렬화 VS 인스턴스간 병렬화
-- INSTANCE 1
ALTER SYSTEM SET INSTANCE_GROUPS = SEOUL, BUSAN SCOPE = SPFILE ;
-- INSTANCE 2
ALTER SYSTEM SET INSTACNE_GROUPS = BUSAN SCOPE = SPFILE ;
-- DB RESTART
-- 병렬 작업 시 PARALLE_INSTANCE_GROUP 지정 후 작업
ALTER SESSION SET PARALLEL_INSTANCE_GROUP = SEOUL ;
SELECT /+* PARALLEL(A) PARALLEL(B) */ COUNT(*) FROM BIG_SEOUL1 A, BIG_SEOUL2 B
WHERE A.ID = B.ID ;
ALTER SESSION SET PARALLEL_INSTANCE_GROUP = BUSAN ;
SELECT /+* PARALLEL(A) PARALLEL(B) */ COUNT(*) FROM BIG_SEOUL1 A, BIG_SEOUL2 B
WHERE A.ID = B.ID
CREATE TABLE PX_TEST (ID NUMBER, NAME VARCHAR2(100))
PARTITION BY HASH(ID) PARTITIONS 4;
CREATE TABLE PX_TEST2 (ID NUMBER, NAME VARCHAR2(100))
PARTITION BY HASH(ID) PARTITIONS 4 ;
CREATE TABLE PX_TEST3 (ID NUMBER, NAME VARCHAR2(100)) ;
exec dbms_stats.gather_table_stats(ownname => 'OPS$ORACLE', tabname=> 'PX_TEST', cascade => TRUE, estimate_percent => 15) ;
exec dbms_stats.gather_table_stats(ownname => 'OPS$ORACLE', tabname=> 'PX_TEST2', cascade => TRUE, estimate_percent => 15) ;
exec dbms_stats.gather_table_stats(ownname => 'OPS$ORACLE', tabname=> 'PX_TEST3', cascade => TRUE, estimate_percent=> 15) ;
-- PX_TEST 테이블: 파티션수가 4인 해시 파티션
SQL> CREATE TABLE PX_TEST(ID NUMBER, NAME VARCHAR2(100))
PARTITION BY HASH(ID) PARTITIONS 4;
-- PX_TEST2 테이블: 파티션수가 4인 해시 파티션
SQL> CREATE TABLE PX_TEST2(ID NUMBER, NAME VARCHAR2(100))
PARTITION BY HASH(ID) PARTITIONS 4;
-- PX_TEST3 테이블: 파티션 없는 테이블
SQL> CREATE TABLE PX_TEST3(ID NUMBER, NAME VARCHAR2(100));
SELECT /*+ PARALLEL(A) PARALLEL(B) */ COUNT(*)
FROM PX_TEST A, PX_TEST2 B
WHERE A.ID = B.ID
---> 두 테이블은 파티션 구성이 동일하므로 전체 파티션 지향 조인으로 풀린다.
SELECT STATEMENT ALL_ROWS-Cost : 33882
SORT AGGREGATE
PX COORDINATOR
PX SEND QC (RANDOM)
SORT AGGREGATE
PX PARTITION HASH ALL <--- 전체 파티션 지향 조인을 의미
HASH JOIN
TABLE ACCESS FULL OWI.PX_TEST2(2)
TABLE ACCESS FULL OWI.PX_TEST(1)
SELECT /*+ PARALLEL(A) PARALLEL(B) */ COUNT(*)
FROM PX_TEST A, PX_TEST3 B
WHERE A.ID = B.ID
---> 두 테이블은 파티션 구성이 다르므로 부분 파티션 지향 조인으로 풀린다.
SELECT STATEMENT ALL_ROWS-Cost : 41720
SORT AGGREGATE
PX COORDINATOR
PX SEND QC (RANDOM)
SORT AGGREGATE
HASH JOIN
PX RECEIVE
PX SEND PARTITION (KEY) <--- PX_TEST3는 파티션이 없으므로 논리적인 파티션 생성
PX BLOCK ITERATOR
TABLE ACCESS FULL OWI.PX_TEST3(2)
PX PARTITION HASH ALL <--- PX_TEST는 파티션이 이루어져 있으므로 파티션 스캔
TABLE ACCESS FULL OWI.PX_TEST(1)
SELECT /*+ PARALLEL(A) PARALLEL(B) */ COUNT(*)
FROM PX_TEST3 A, PX_TEST3 B
WHERE A.ID = B.ID
---> 두 테이블은 파티션이 없으므로 일반 조인으로 풀린다.
SELECT STATEMENT ALL_ROWS-Cost : 40564
SORT AGGREGATE
PX COORDINATOR
PX SEND QC (RANDOM)
SORT AGGREGATE
HASH JOIN
PX RECEIVE
PX SEND <--- PX_TEST3는 파티션이 이루어져 있지 않으므로 단순 병렬 스캔
PX BLOCK ITERATOR
TABLE ACCESS FULL OWI.PX_TEST3(1)
PX RECEIVE
PX SEND <--- PX_TEST3는 파티션이 이루어져 있지 않으므로 단순 병렬 스캔
PX BLOCK ITERATOR
TABLE ACCESS FULL OWI.PX_TEST3(2)