행위

"병렬 쿼리 튜닝"의 두 판 사이의 차이

DB CAFE

(병렬 처리 개수 조회)
(DML문 에서도 SELECT 절만 PARALLEL 힌트를 사용하면 될까?)
153번째 줄: 153번째 줄:
 
# 사용법
 
# 사용법
 
==== DML문 에서도 SELECT 절만 PARALLEL 힌트를 사용하면 될까? ====
 
==== DML문 에서도 SELECT 절만 PARALLEL 힌트를 사용하면 될까? ====
# DML에서 CONVENTIONAL / DIRECT PATH 차이점? 12c 에서 처리 방법
+
# DML에서 CONVENTIONAL / DIRECT PATH 차이점?  
 +
##
 +
## Direct Path
 +
: 병렬방식으로 Full Scan 할 때는 버퍼 캐시를 거치지 않고 곧바로 PGA 영역으로 읽어들이는 Direct Path Read 방식을 사용
 +
 
 +
12c 에서 처리 방법
 
# DML 병렬 처리
 
# DML 병렬 처리
 
## DML 작업에서는 Paralle 힌트를 주어도 QC 가 작업 담당
 
## DML 작업에서는 Paralle 힌트를 주어도 QC 가 작업 담당

2023년 1월 13일 (금) 18:11 판

thumb_up 추천메뉴 바로가기


목차

1 병렬 쿼리 튜닝[편집]

1.1 병렬처리 핵심은?[편집]

1.1.1 그래뉼[편집]

android The basic unit of work in parallelism is a called a granule.

Oracle Database divides the operation executed in parallel (for example, a table scan, table update, or index creation) into granules.


  1. 병렬로 처리할때 일의 최소 단위
1.1.1.1 블록 그래뉼[편집]
  1. PX BLOCK ITERATOR 라고 표시
  2. QC는 테이블로부터 읽어야할 범위의 블록 GRANULE로서 각 병렬 서버에게 할당
-------------------------------------------------------------------------------------------------
|Id|      Operation          |  Name  |Rows|Bytes|Cost%CPU|  Time  |Pst|Pst|  TQ |INOUT|PQDistri|
-------------------------------------------------------------------------------------------------
| 0|SELECT STATEMENT         |        |  17| 153 |565(100)|00:00:07|   |   |     |     |        |
| 1| PX COORDINATOR          |        |    |     |        |        |   |   |     |     |        |
| 2|  PX SEND QC(RANDOM)     |:TQ10001|  17| 153 |565(100)|00:00:07|   |   |Q1,01|P->S |QC(RAND)|
| 3|   HASH GROUP BY         |        |  17| 153 |565(100)|00:00:07|   |   |Q1,01|PCWP |        |
| 4|    PX RECEIVE           |        |  17| 153 |565(100)|00:00:07|   |   |Q1,01|PCWP |        |
| 5|     PX SEND HASH        |:TQ10000|  17| 153 |565(100)|00:00:07|   |   |Q1,00|P->P | HASH   |
| 6|      HASH GROUP BY      |        |  17| 153 |565(100)|00:00:07|   |   |Q1,00|PCWP |        |
==========> 블록 이터레이터로 표시됨 
| 7|       PX BLOCK ITERATOR |        | 10M| 85M | 60(97) |00:00:01| 1 | 16|Q1,00|PCWC |        |
|*8|        TABLE ACCESS FULL|  SALES | 10M| 85M | 60(97) |00:00:01| 1 | 16|Q1,00|PCWP |        |
-------------------------------------------------------------------------------------------------
1.1.1.2 파티션 그래뉼[편집]
  1. PX PARTITION RANGE ALL 또는 PX PARTITION RANGE ITERATOR 라고 표시
  2. 사용되는 시기
    1. Partition-Wise조인 시
    2. 파티션 인덱스를 병렬로 스캔할 시
    3. 파티션 인덱스를 병렬로 갱신할 때
    4. 파티션 테이블 또는 파티션 인덱스를 병렬로 생성할 때
---------------------------------------------------------------------------------------------------
|Id|      Operation                |  Name  |Rows|Byte|Cost%CPU|  Time  |Ps|Ps|  TQ |INOU|PQDistri|
---------------------------------------------------------------------------------------------------
| 0|SELECT STATEMENT               |        |  17| 153|   2(50)|00:00:01|  |  |     |    |        |
| 1| PX COORDINATOR                |        |    |    |        |        |  |  |     |    |        |
| 2|  PX SEND QC(RANDOM)           |:TQ10001|  17| 153|   2(50)|00:00:01|  |  |Q1,01|P->S|QC(RAND)|
| 3|   HASH GROUP BY               |        |  17| 153|   2(50)|00:00:01|  |  |Q1,01|PCWP|        |
| 4|    PX RECEIVE                 |        |  26| 234|    1(0)|00:00:01|  |  |Q1,01|PCWP|        |
| 5|     PX SEND HASH              |:TQ10000|  26| 234|    1(0)|00:00:01|  |  |Q1,00|P->P| HASH   |
==========> 파티션 RANGE ... 로 표시됨 
| 6|      PX PARTITION RANGE ALL   |        |  26| 234|    1(0)|00:00:01|  |  |Q1,00|PCWP|        |
| 7|       TABLEACCESSLOCAL INDEX ROWID|SALES| 26| 234|    1(0)|00:00:01| 1|16|Q1,00|PCWC|        |
|*8|        INDEX RANGE SCAN       |SALES_CUST|26|    |    1(0)|00:00:01| 1|16|Q1,00|PCWP|        |
---------------------------------------------------------------------------------------------------

1.1.2 생산자 VS 소비자[편집]

?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy9Qa0%2FbtqytV7dIAq%2FK95i8dY3X43nzrZhvhkPrk%2Fimg.png

1.1.3 DOP 많을수록 좋을까?[편집]

1.1.4  병렬퀴리튜닝의 관점은? 병렬의 갯수인가? 분산의 정도인가?[편집]

각 병렬 프로세스들이 독립적으로 일 할 수 있도록 데이터 적절하게 분배



1.1.5 병렬 PLAN 해석하는 방법[편집]

--------------------------------------------------------------------------------------------------------------------
| Id  | Operation                  | Name     | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
--------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |          |    14 |  1638 |     7  (29)| 00:00:01 |        |      |            |
|   1 |  PX COORDINATOR            |          |       |       |            |          |        |      |            |
|   2 |   PX SEND QC (ORDER)       | :TQ10002 |    14 |  1638 |     7  (29)| 00:00:01 |  Q1,02 | P->S | QC (ORDER) |
|   3 |    SORT ORDER BY           |          |    14 |  1638 |     7  (29)| 00:00:01 |  Q1,02 | PCWP |            |
|   4 |     PX RECEIVE             |          |    14 |  1638 |     6  (17)| 00:00:01 |  Q1,02 | PCWP |            |
|   5 |      PX SEND RANGE         | :TQ10001 |    14 |  1638 |     6  (17)| 00:00:01 |  Q1,01 | P->P | RANGE      |
|*  6 |       HASH JOIN            |          |    14 |  1638 |     6  (17)| 00:00:01 |  Q1,01 | PCWP |            |
|   7 |        BUFFER SORT         |          |       |       |            |          |  Q1,01 | PCWC |            |
|   8 |         PX RECEIVE         |          |     4 |   120 |     3   (0)| 00:00:01 |  Q1,01 | PCWP |            |
|   9 |          PX SEND BROADCAST | :TQ10000 |     4 |   120 |     3   (0)| 00:00:01 |        | S->P | BROADCAST  |
|  10 |           TABLE ACCESS FULL| DEPT     |     4 |   120 |     3   (0)| 00:00:01 |        |      |            |
|  11 |        PX BLOCK ITERATOR   |          |    14 |  1218 |     2   (0)| 00:00:01 |  Q1,01 | PCWC |            |
|  12 |         TABLE ACCESS FULL  | EMP      |    14 |  1218 |     2   (0)| 00:00:01 |  Q1,01 | PCWP |            |
--------------------------------------------------------------------------------------------------------------------


  1. S->P 직렬 PARALLEL_FROM_SERIAL QC가 읽은 데이터를 테이블 큐를 통해 병렬서버 프로세스에게 전송
  2. P->S 병렬 PARALLEL_TO_SERIAL 각 병렬서버 프로세스가 처리한 데이터를 QC에게 전송
  3. P->P 병렬 PARALLEL_TO_PARALLEL 데이터를 재분배(redistribution)하는 오퍼레이션 ,데이터를 정렬 또는 그룹핑하거나 조인을 위해 동적으로 파티셔닝할 때 사용
  4. PCWP 병렬 PARALLEL_COMBINED_WITH_PARENT 한 서버집합이 현재스텝과 부모스텝을 모두 처리
  5. PCWC 병렬 PARALLEL_COMBINED_WITH_CHILD 한 서버집합이 현재스텝과 자식스텝을 모두 처리
  6. [___] 직렬 SERIAL 공백인 경우 SERIAL 방식으로 처리



  1. RANGE
    1. Order By / Group By 를 병렬로 처리할 때 사용
    2. 정렬작업을 맡은 두번째 서버집합의 프로세스마다 처리범위를 지정하고 나서
    3. 데이터를 읽는 첫번째 서버집합이 정렬키값에 따라 정해진 범위에 해당하는 두번째 프로세스에게 분배하는 방식
    4. QC는 작업범위를 할당하며, 정렬작업에는 참여하지 않는다.
    5. 정렬결과를 순서대로 받아서 사용자에게 전송하는 역할만 담당
  2. HASH
    1. 조인 / Hash Group By 를 병렬로 처리할 때 사용
    2. 조인 키나 Group By 키값을 해시함수에 적용하여 리턴되는 값에 따라 데이터를 분배
    3. P->P 뿐만 아니라 S->P 방식으로 이루어 질수도 있다.
  3. BROADCAST
    1. QC 또는 첫번째 서버집합의 프로세스들이 각각 읽은 데이터를 두번째 서버집합의 "모든" 병렬프로세스에게 전송하는 방식
    2. 병렬 조인에서 크기가 매우 작은 테이블이 있을 때 사용되며 P->P 뿐만 아니라 S->P 방식으로 이루어 진다.
    3. 작은 테이블은 병렬로 읽지 않을 때가 많으므로 오히려 S->P가 일반적임
  4. KEY
    1. 특정 컬럼(들)을 기준으로 테이블 또는 인덱스를 파티셔닝할때 사용하는 분배 방식
    2. 실행계획에는 'PARTITION (KEY)'로 표시된다.(줄여서 'PART (KEY)').
  5. ROUND-ROBIN
    1. 파티션키, 정렬키, 해시함수에 의존하지 않고 반대편 정렬 서버에 무작위로 데이터 분배
    2. 골고루 분배되도록 ROUND-ROBIN 방식 사용




1.1.5.1 SQL 플랜상 튜닝 검토 사항[편집]

android # broadcast 는 소량테이블에 적합

  1. hash 는 대량 테이블에 적합
  2. P->S 는 튜닝 대상임. P->P로 바꿀수 있는 방법을 검토.sql수정도 좋다.
  3. round-robin 은 튜닝 대상임
  4. merge 나 insert ,delete문에만 주로 Parallel 힌트 사용. 하위 select 문에서는 가급적 지양 , 1:1 관계를 지향한다
  5. part key 플랜도 튜닝 대상. pq_disiribute(A hash hash) 힌트로 검토


1.2 병렬처리 올바른 사용법은?[편집]


1.2.1 병렬 힌트를 어디에 어떻게 써야 하나?[편집]


1.2.2 DDL, DML 병렬처리[편집]

  1. DML
    1. SELECT
    2. INSERT
    3. UPDATE
    4. DELETE
  2. DDL
    1. CREATE
    2. ALTER
    3. DROP
    4. RENAME
    5. TRUNCATE

1.3 진행중인 병렬 처리가 잘되는지 궁금한데 ?[편집]

병렬_쿼리_모니터링

1.3.1 관련 뷰[편집]

1.3.2 토드에서 확인 방법[편집]

1.3.3 REAL MONITOR[편집]

  1. 사용법

1.3.4 DML문 에서도 SELECT 절만 PARALLEL 힌트를 사용하면 될까?[편집]

  1. DML에서 CONVENTIONAL / DIRECT PATH 차이점?
    1. Direct Path
병렬방식으로 Full Scan 할 때는 버퍼 캐시를 거치지 않고 곧바로 PGA 영역으로 읽어들이는 Direct Path Read 방식을 사용

12c 에서 처리 방법

  1. DML 병렬 처리
    1. DML 작업에서는 Paralle 힌트를 주어도 QC 가 작업 담당
    2. 병렬 DML 가능하도록 처리
      1. 12c 이전 에는 세션에 적용
SQL> alter session enable parallel dml;
      1. 12c 부터는 힌트로 적용
/*+ ENABLE_PARALLEL_DML */

  1. DML 병렬 처리시 주의사항

android #DML 병렬 처리시 주의사항

    1. 테이블 전체에 Exclusive 모드로 Lock 획득하므로 주의
    2. 커밋/롤백을 해야 SELECT 가능 함.



1.3.4.1 데이터 전환시 사용하는 병렬처리[편집]
-- 세션에서 병렬 쿼리 작업 절차
ALTER SESSION ENABLE PARALLEL DML;
ALTER SESSION SET HASH_AREA_SIZE          = 1024000000;
ALTER SESSION SET SORT_AREA_SIZE          = 2147483647;
ALTER SESSION SET SORT_AREA_RETAINED_SIZE = 2147483647;
ALTER SESSION SET WORKAREA_SIZE_POLICY    = MANUAL; 
-- 사용자가 지정한 sort_area_size가 모든  병렬 서버에게 적용. 
-- sort_area_size를 크게 설정한 상태에서 지나치게 큰 병렬도를 지정하면
-- OS 레벨에서 페이징이 발생하고 심할 경우 시스템을 마비시킬 수 있음.
ALTER SESSION SET SKIP_UNUSABLE_INDEXES = TRUE;
ALTER SESSION SET DB_FILE_MULTIBLOCK_READ_COUNT=256; -- AIX는 최대 512 

ALTER SESSION SET "_sort_multiblock_read_count"     = 256;
ALTER SESSION SET "_db_file_optimizer_read_count"   = 256;
ALTER SESSION SET "_db_file_exec_read_count"        = 256;
ALTER SESSION SET "_serial_direct_read"             = TRUE;
  1. WAIT EVENT 확인 방법은?

Px wait event.png

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
;
    1. 병렬쿼리가 대기 하고 있는경우?

1.4 병렬 처리가 왜 안되지 ?[편집]

1.4.1 병렬 환경 파리미터 조회[편집]

SELECT *
  FROM V$PARAMETER
 WHERE NAME LIKE '%parallel%' -- 'parallel_threads_per_cpu' -- 2
  1. 병렬 작업에 대한 리소스 제한을 설정하는 매개변수
    1. PARALLEL_FORCE_LOCAL
      1. 병렬로 실행되는 SQL 문이 Oracle RAC 환경의 단일 인스턴스로 제한되는지 여부를 지정
      2. 이 매개변수를 TRUE로 설정하면 쿼리 코디네이터가 실행 중인 단일 Oracle RAC 인스턴스로 처리되는 병렬 서버의 범위를 제한
      3. PARALLEL_FORCE_LOCAL 매개변수의 권장 값은 FALSE
    2. PARALLEL_MAX_SERVERS
      1. 인스턴스에 대한 최대 병렬 실행 프로세스 및 병렬 복구 프로세스 수를 지정
      2. 수요가 증가함에 따라 Oracle Database는 인스턴스 시작 시 생성된 수에서 이 값까지 프로세스 수를 늘림.
      3. DOP(병렬 처리 수준) 특성이 더 높은 테이블의 병렬 쿼리에는 기본값이 충분하지 않을 수 있습니다.
      4. 더 높은 DOP의 쿼리를 실행하려면 2 x DOP x NUMBER_OF_CONCURRENT_USERS
    3. PARALLEL_MIN_PERCENT
      1. 사용 중인 애플리케이션에 따라 사용자가 허용 가능한 DOP를 기다림.
      2. PARALLEL_MIN_PERCENT 매개변수의 권장 값은 0.
      3. 0 이외의 값으로 설정하면 지정된 시간에 시스템에서 요청된 DOP를 충족할 수 없을 때 Oracle 데이터베이스에서 오류를 반환 함.
      4. 예를 들어 PARALLEL_MIN_PERCENT를 50으로 설정하고 DOP가 적응형 알고리즘이나 리소스 제한으로 인해 50% 이상 감소하면 Oracle Database는 ORA-12827을 반환.
      5. ORA-12827: insufficient parallel query slaves available
    4. PARALLEL_MIN_SERVERS
      1. 병렬 작업을 위해 예약된 단일 인스턴스에서 시작할 프로세스 수를 지정
      2. PARALLEL_MIN_SERVERS를 설정하면 시작 비용과 메모리 사용량의 균형을 맞춤.
      3. PARALLEL_MIN_SERVERS를 사용하여 시작된 프로세스는 데이터베이스가 종료될 때까지 종료되지 않음.
    5. PARALLEL_MIN_TIME_THRESHOLD
      1. 쿼리가 자동 병렬 처리 수준을 고려하여 쿼리가 가져야 하는 최소 실행 시간을 지정.
      2. 자동 병렬 처리 수준은 PARALLEL_DEGREE_POLICY가 AUTO 또는 LIMITED로 설정된 경우에만 활성화 됨.
    6. PARALLEL_SERVERS_TARGET
      1. 명령문 큐잉이 사용되기 전에 병렬 명령문을 실행할 수 있는 병렬 서버 프로세스 수를 지정
      2. PARALLEL_DEGREE_POLICY가 AUTO로 설정된 경우 시스템에서 현재 사용 중인 병렬 프로세스 수가 PARALLEL_SERVERS_TARGET보다 크거나 같으면 병렬 실행이 필요한 명령문이 대기함.
      3. 시스템에서 허용되는 최대 병렬 서버 프로세스 수가 아님(PARALLEL_MAX_SERVERS에 의해 제어됨).
      4. 그러나 PARALLEL_SERVERS_TARGET 및 병렬 명령문 큐잉은 병렬 실행이 필요한 각 명령문에 필요한 병렬 서버 리소스가 할당되고 시스템이 너무 많은 병렬 서버 프로세스로 플러딩되지 않도록 하는 데 사용
    7. SHARED_POOL_SIZE
      1. 병렬 실행에는 직렬 SQL 실행에 필요한 것 외에 메모리 리소스가 필요
      2. 추가 메모리는 쿼리 서버 프로세스와 쿼리 코디네이터 간의 통신 및 데이터 전달에 사용
      3. Oracle Database는 공유 풀에서 쿼리 서버 프로세스를 위한 메모리를 할당. 다음과 같이 공유 풀을 조정.
        1. 공유 커서 및 저장 프로시저와 같은 공유 풀의 다른 클라이언트를 허용.
        2. 값이 크면 다중 사용자 시스템에서 성능이 향상되지만 값이 작으면 메모리 사용량이 줄어듬.
        3. 그런 다음 병렬 실행에 사용되는 버퍼 수를 모니터링하고 shared pool PX msg pool을 V$PX_PROCESS_SYSSTAT 보기의 출력에 보고된 현재 최고 수위 표시와 비교

1.4.2 병렬처리가 안되는경우[편집]


1.4.3 서버에서 프로세스를 할당 받지 못할때[편집]


1.4.4 insert ~ select 의 병렬도가 다를때[편집]


1.4.5 파티션닝 테이블에 1개파티션만 타는경우[편집]


1.4.6 LOB 컬럼 포함시[편집]

  1. lob 컬럼 포함시 => 오라클 19c 부터기능

1.4.7 DB 링크[편집]


1.5 병렬 힌트사용 방법
[편집]

1.5.1 PQ_DISTRIBUTE[편집]


1.5.2 PQ_REPLICATE / NO_PQ_REPLICATE(대량테이블)[편집]


1.5.3 PQ_SKEW/NO_PQ_SKEW[편집]


1.5.4 BF 블름필터(Bloom Filter)[편집]


1.5.5 PQ_DISTRIBUTE_WINDOW[편집]


1.5.6 PQ_EXPAND_TABLE / NO_PQ_EXPAND_TABLE[편집]

  1. PQ_EXPAND_TABLE
    1. 파티션테이블인 경우 한곳에 편중된 파티션이 있을때, 옵티마이저가 UNION 절로 변경하여 편중된 파티션과 다른 파티션을 나누어 병렬처리로 수행함.
    2. (예) 인라인뷰내 파티션테이블을 (GROUP BY하는 경우)발생함
  • 튜닝 사례 1 : 한곳에 치중된 파티션을 UNION ALL 로 분리
SELECT *
  FROM 
(SELECT /*+ PQEXPAND_TABLE(A2) */
        AZ.SRV_INSTLID
      , A2.CYKIM_TIMPL_ID
      , A2.CYKIM_WRT_YMD
      , A2.CYKIM_WRT_DGR
      , MIN(A2.DCRY_LNNO) AS DCRY_LNNO 
  FROM TB_BIG_PART A2 -- 파티션테이블 
 WHERE SUBSTR(A2.CYKIM_TMPL_ID, 0, 2) = 'am'
 GROUP BY A2.SRV_INST_ID
        , A2.CYKIM_TMP_ID 
        , A2.CYKIM_WRT_YMD
        , A2.CYKIM_WRT_DGR
) A
, TB_CYKIM_SPRV B
.....
  • 튜닝 사례 2 : 한곳에 치중된 파티션을 UNION ALL 로 분리 하지 않음.
SELECT *
  FROM 
(SELECT /*+ NO_PQEXPAND_TABLE(A2) */
        AZ.SRV_INSTLID
      , A2.CYKIM_TIMPL_ID
      , A2.CYKIM_WRT_YMD
      , A2.CYKIM_WRT_DGR
      , MIN(A2.DCRY_LNNO) AS DCRY_LNNO 
  FROM TB_BIG_PART A2 -- 파티션테이블의  한곳의 파티션에 치중됨, 예를 들어 2000년 이전 데이터는 PT_2001파티션에 1억건 존재 , 나머지는 1백만건 
 WHERE SUBSTR(A2.CYKIM_TMPL_ID, 0, 2) = 'am'
 GROUP BY A2.SRV_INST_ID
        , A2.CYKIM_TMP_ID 
        , A2.CYKIM_WRT_YMD
        , A2.CYKIM_WRT_DGR
) A
, TB_CYKIM_SPRV B
.....

1.5.7 PQ_CONCURRENT_UNION[편집]


1.5.8 PQ_FILTER[편집]

/*+ PQ_FILTER(SERIAL | NONE | HASH | RANDOM) */ -- 4개중 택1
  1. 병렬서버에서 서브쿼리를 필터링할수 있는 기능.
  2. 서브쿼리 필터링은 일반적으로 메인쿼리가 모두 수행된 후 수행함.
  3. HASH방식과 RANDOM방식은 추가적인 버퍼링이 필요하므로 특별한 경우가 아니면 NONE 방식으로 사용하는것이 일반적일것으로 판단함.
  4. 다수의 서브쿼리 수행시 2개의 서브쿼리 모두 병렬서버에서 필터링됨.
=> ORDER_SUBQ 힌트(12c 이후) 로 서브쿼리의 수행순서 조정가능함.
  • PQ_FILTER 사용예시 (with NO_UNNEST 힌트)
SELECT /* + PARALLEL(2) PQ_FILTER(HASH) */
       *
  FROM T1 A
 WHERE EXISTS (SELECT /*+ NO_UNNEST */
                      1
                 FROM T2 B
                WHERE B.C1 = A.C1)
  • 서브 쿼리가 2개일 때 순서 조정 예시
SELECT /*+ PARALLEL(2) PQ_FILTER(NONE) 
           ORDER_SUBQ(@MAIN @SUB2 @SUB1) QB_NAME(MAIN) */
       * 
 FROM T1 A
WHERE EXISTS (SELECT /*+ NO_UNNEST QB_NAME(SUB1) */
                      1
                 FROM T2 B
                WHERE B.C1 = A.C1)
  AND EXISTS (SELECT /*+ NO_UNNEST QB_NAME(SUB2) */
                      1
                 FROM T3 C
                WHERE C.C1 = A.C1)


QC 에서 서브쿼리를 필터링함


FILTER
  PX COORDINATOR
    PX SEND QC(RANDOM)
      PX BLOCK ITERATOR
        TABLE ACCESS FULL T1
  INDEX RANGE SCAN IX_T2


  1. 메인쿼리를 분배하지 않고 병렬서버에서 서브쿼리를 필터링함.
  2. 병렬서버가 T1 테이블을 블록 그래뉼로 조회하고, 조회결과로 서브쿼리를 필터링하여 QC로 결과를 전송하는 방식


PX COORDINATOR
  PX SEND QC(RANDOM)
   FILTER
     PX BLOCK ITERATOR.
        TABLE ACCESS FULL 11
     INDEX RANGE SCAN IX_12
PX COORDINATOR
  PX SEND QC(RANDOM)
    FILTER
      PX BLOCK ITERATOR
         TABLE ACCESS FULL T1
    INDEX RANGE SCAN X_13
    INDEX RANGE SCAN IX_12


  1. 메인 쿼리를 HASH 방식으로 분배 한후, 병렬서버에서 서브쿼리를 필터링함.
  2. HASH방식은 조인조건인 C1 컬럼의 해시값으로 분배 되기 때문에 서브쿼리 캐싱 효율을 높이는 목적으로 활용가능.


PX COORDINATOR
  PX SEND QC(RANDOM)
    BUFFER SORT
      FILTER
        PX RECEIVE
           PX SEND HASH
              PX BLOCK ITERATOR
                TABLE ACCESS FULL T1
           INDEX RANGE SCAN IX_T2


  1. 메인쿼리를 RANDOM 방식으로 분배한후, 병렬서버에서 서브쿼리를 필터링함.
  2. RANDOM 방식은 read by other session등 의 블럭경합을 해소하는 목적으로 활용가능


PX COORDINATOR
  PX SEND QC(RANDOM)
    BUFFER SORT
      FILTER
        PX RECEIVE
           PX SEND ROUND-ROBIN
              PX BLOCK ITERATOR 
                TABLE ACCESS FULL T1
              INDEX RANGE SCAN IX_T2

1.5.9 파티션[편집]

  1. USE PARTITION_WISE_DISTINCT
  2. USE PARTITION_WISE_GBY
  3. USE PARTITION_WISE_WIF

  • .오라클은 내부적 으로 어떤 힌트를 사용하고 있는지 볼까 ?
    • OUTLINE

1.6 튜닝포인트를 찾아라[편집]


1.6.1 심플하게 튜닝 하는 방법은 없을까?[편집]


1.6.2 스칼라퀴리는 인라인뷰로 변경을 검토하라[편집]


1.6.3 BROADCAST 테이블을 찾아라[편집]


1.6.4 튜닝대상을 찾아라[편집]


1.6.5 조인이 효율적인지 검토 하라[편집]


1.7 입력/수정 성능저하시 검토 사항[편집]


1.7.1 INSERT 처리가 느릴때(SELECT~INSERT시 SELECT는 빠른데 INSERT가 느린경우)[편집]


1.7.2 시퀀스를 사용하는경우[편집]


1.7.3 V$SSESSION_WAIT_CLASS[편집]


1.7.4 DB링크 병렬처리 주의사항[편집]



1.7.5 병렬 처리 개수 조회[편집]

  • 패러럴 실행 메시지 사이즈 32K
alter system set parallel_execution_message_size = 32768; -- 16384 -- 기본

1.8 그외 병렬 처리시 주의 사항[편집]

  1. 실행계획에서 P ->P가 나타날 때면 지정한 병렬도의 2배수만큼 병렬 프로세스 필요
  2. 쿼리 블록마다 병렬도를 다르게 지정한 경우, 여러 가지 우선 순위와 규칙에 따라 최종 병렬도가 결정됨, 병렬도를 같게 지정하는 것이 바람직 함.
  3. parallel_index 힌트를 사용할 때는 반드시 index 또는 index_ffs 힌트를 사용
    1. 옵티마이저에 의해 Full table Scan이 선택될 경우 parallel_index 힌트는 무시 됨
  4. 병렬 DML 수행시 Exculsive 모드 테이블 Lock이 걸리므로 업무 트랜잭션이 발생하는 주간에는 삼가
  5. 테이블이나 인덱스를 빠르게 생성하려고 parallel 옵션 을 사용했다면 작업을 완료 후 즉시 noparallel로 변경 할것
  6. 부분범위처리 방식으로 조회하면서 병렬 쿼리를 사용한 때에는 필요한 만큼 데이터를 Fetch 하고 나서 곧바로 커서를 닫아 주어야 함
    1. Toad나 Orange 처럼 부분범위처리를 지원하는 쿼리 툴에서는 EOF에 도달하기 전까지
    2. 커서를 오픈한 채로 유지하기 때문에 오라클은 병렬 서버들을 해제하지 못하고 대기 상태에 머물도록 한다.
    3. 이는 불필요한 리소스를 낭비하는 결과를 초래하므로 조회가 끝나자마자
    4. select * from dual 같은 문장을 수행해 병렬 쿼리의 커서를 닫아 주어야 한다.