병렬 쿼리에서 사용자 정의 함수의 동작 #2

2021. 12. 24.·Oracle/Performance

병렬 쿼리에서 패키지 변수를 사용한 사용자 정의 함수는 PARALLEL_ENABLE 키워드의 기술 여부에 따라 동작이 달라질 수 있습니다.

 

테스트를 위해 아래와 같이 테이블을 생성하겠습니다.

-- 1
DROP TABLE t1 PURGE;
CREATE TABLE t1 AS SELECT ROWNUM AS c1, LPAD ('X', 4000, 'X') AS c2 FROM XMLTABLE ('1 to 8');

 

아래 f1, f2 함수는 세션 ID와 pkg1.gv1 패키지 변수에 1을 더한 값을 반환합니다. 아울러 f2 함수에만 PARALLEL_ENABLE 키워드를 사용합니다.

-- 2-1
DROP PACKAGE pkg1;

CREATE OR REPLACE PACKAGE pkg1
IS
    gv1 NUMBER := 0;
END;
/

-- 2-2
CREATE OR REPLACE FUNCTION f1 (i_v1 IN NUMBER)
    RETURN VARCHAR2
IS
BEGIN
    pkg1.gv1 := pkg1.gv1 + 1;
    RETURN SYS_CONTEXT ('USERENV', 'SID') || ',' || pkg1.gv1;
END;
/

-- 2-3
CREATE OR REPLACE FUNCTION f2 (i_v1 IN NUMBER)
    RETURN VARCHAR2
    PARALLEL_ENABLE
IS
BEGIN
    pkg1.gv1 := pkg1.gv1 + 1;
    RETURN SYS_CONTEXT ('USERENV', 'SID') || ',' || pkg1.gv1;
END;
/

 

아래 쿼리는 QC가 f1 함수를 수행하여 1개의 세션 ID가 반환됩니다. 패키지 변수는 세션 레벨에서 할당되므로 일관된 결과를 보장하기 위해 QC가 f1 함수를 실행한 것입니다.

-- 3
SELECT /*+ PARALLEL(4) */
       f1 (c1) AS sid
  FROM t1;

SID
-----
277,1
277,2
277,3
277,4
277,5
277,6
277,7
277,8

8 행이 선택되었습니다.

----------------------------------------------------------------------
| Id  | Operation            | Name     |    TQ  |IN-OUT| PQ Distrib |
----------------------------------------------------------------------
|   0 | SELECT STATEMENT     |          |        |      |            |
|   1 |  PX COORDINATOR      |          |        |      |            | -- !
|   2 |   PX SEND QC (RANDOM)| :TQ10000 |  Q1,00 | P->S | QC (RAND)  |
|   3 |    PX BLOCK ITERATOR |          |  Q1,00 | PCWC |            |
|   4 |     TABLE ACCESS FULL| T1       |  Q1,00 | PCWP |            |
----------------------------------------------------------------------

 

아래 쿼리는 병합되지 않은 인라인 뷰 내에 f1 함수를 사용합니다. 실행 계획 1번에 PX COORDINATOR FORCED SERIAL 오퍼레이션이 표시됩니다. QC가 f1 함수를 수행하여 1개의 세션 ID가 반환되고 앞선 쿼리에 이어서 1씩 증가한 pkg1.gv1 패키지 변수 값이 반환됩니다.

-- 4
SELECT /*+ PARALLEL(4) */
       *
  FROM (SELECT /*+ NO_MERGE */
               f1 (c1) AS sid
          FROM t1);

SID
------
277,9
277,11
277,12
277,13
277,14
277,15
277,16
277,17

8 행이 선택되었습니다.

------------------------------------------------------------------------------
| Id  | Operation                    | Name     |    TQ  |IN-OUT| PQ Distrib |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |          |        |      |            |
|   1 |  PX COORDINATOR FORCED SERIAL|          |        |      |            | -- !
|   2 |   PX SEND QC (RANDOM)        | :TQ10000 |  Q1,00 | P->S | QC (RAND)  |
|   3 |    VIEW                      |          |  Q1,00 | PCWP |            |
|   4 |     PX BLOCK ITERATOR        |          |  Q1,00 | PCWC |            |
|   5 |      TABLE ACCESS FULL       | T1       |  Q1,00 | PCWP |            |
------------------------------------------------------------------------------

 

아래 쿼리는 PX 서버가 f2 함수를 수행하여 4개의 세션 ID가 반환됩니다. 함수에 PARALLEL_ENABLE 키워드를 사용하면  PX 서버 세션에 pkg1.gv1 패키지 변수가 할당됩니다. 이로 인해 세션 ID 별로 1씩 증가한 pkg1.gv1 패키지 변수 값이 반환됩니다. 

-- 5
SELECT /*+ PARALLEL(4) */
       f2 (c1) AS sid
  FROM t1;

SID
-----
22,1
22,2
394,1
394,2
267,1
267,2
395,1
395,2

8 행이 선택되었습니다.

----------------------------------------------------------------------
| Id  | Operation            | Name     |    TQ  |IN-OUT| PQ Distrib |
----------------------------------------------------------------------
|   0 | SELECT STATEMENT     |          |        |      |            |
|   1 |  PX COORDINATOR      |          |        |      |            |
|   2 |   PX SEND QC (RANDOM)| :TQ10000 |  Q1,00 | P->S | QC (RAND)  |
|   3 |    PX BLOCK ITERATOR |          |  Q1,00 | PCWC |            | -- !
|   4 |     TABLE ACCESS FULL| T1       |  Q1,00 | PCWP |            |
----------------------------------------------------------------------

 

아래 쿼리는 병합되지 않은 인라인 뷰 내에 f2 함수를 사용합니다. 새로운 PX 서버 세션에 pkg1.gv1 패키지 변수가 할당되므로 세션 ID 별로 1씩 증가한 pkg1.gv1 패키지 변수 값이 반환됩니다.

-- 6
SELECT /*+ PARALLEL(4) */
       *
  FROM (SELECT /*+ NO_MERGE */
               f2 (c1) AS sid
          FROM t1);

SID
-----
395,1
395,2
22,1
22,2
394,1
394,2
267,1
267,2

8 행이 선택되었습니다.

-----------------------------------------------------------------------
| Id  | Operation             | Name     |    TQ  |IN-OUT| PQ Distrib |
-----------------------------------------------------------------------
|   0 | SELECT STATEMENT      |          |        |      |            |
|   1 |  PX COORDINATOR       |          |        |      |            |
|   2 |   PX SEND QC (RANDOM) | :TQ10000 |  Q1,00 | P->S | QC (RAND)  |
|   3 |    VIEW               |          |  Q1,00 | PCWP |            | -- !
|   4 |     PX BLOCK ITERATOR |          |  Q1,00 | PCWC |            |
|   5 |      TABLE ACCESS FULL| T1       |  Q1,00 | PCWP |            |
-----------------------------------------------------------------------
저작자표시 비영리 변경금지 (새창열림)
'Oracle/Performance' 카테고리의 다른 글
  • Historical SQL Monitor Report
  • 로우 랜덤 조회
  • 병렬 쿼리에서 사용자 정의 함수의 동작 #1
  • 중복 제거에 대한 DISTINCT 키워드와 GROUP BY 절
정희락
정희락
2007년부터 Oracle Database 성능 최적화에 관심을 가져왔습니다. 현재 한국오라클 Engineered Systems Solution Engineering 팀에서 Solution Engineer로 근무하고 있습니다. 이 블로그는 개인적인 연구 목적으로 운영되며 Oracle 사의 공식적인 입장을 대변하지 않습니다.
  • 정희락
    TunA
    정희락
  • 전체
    오늘
    어제
    • 분류 전체보기 (199)
      • Oracle (171)
        • SQL (33)
        • PLSQL (10)
        • Performance (74)
        • Administration (37)
        • Installation (3)
        • Utilities (1)
        • JSON (8)
        • Vector (5)
      • Exadata (15)
      • SQL*Plus (2)
      • Linux (5)
      • Resources (6)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 도서

    • 불친절한 SQL 프로그래밍
    • 불친절한 PL/SQL 프로그래밍
  • 링크

    • Connor McDonald
    • Frits Hoogland
    • Jonathan Lewis
    • Julian Dontcheff
    • Julian Dyke
    • Kun Sun
    • Maria Colgan
    • Martin Bach
    • Mike Dietrich
    • Tanel Poder
  • 공지사항

  • 인기 글

  • 태그

    12c
    19c
    21c
    23ai
    case study
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
정희락
병렬 쿼리에서 사용자 정의 함수의 동작 #2
상단으로

티스토리툴바