Automatic SQL Transpiler

2023. 4. 14.·Oracle/Performance

Oracle 23c에 Automatic SQL Transpiler 기능이 추가되었습니다. 해당 기능은 단순 표현식을 반환하는 PL/SQL 함수를 SQL 표현식으로 변환해 SQL과 PL/SQL 간의 Context switching을 제거함으로써 성능을 개선합니다.

PL/SQL functions within SQL statements are automatically converted (transpiled) into SQL expressions whenever possible. Transpiling PL/SQL functions into SQL statements can speed up overall execution time.

 

테스트를 위해 아래와 같이 테이블과 함수를 생성하겠습니다. f1 함수는 단순 표현식을 반환합니다.

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

-- 1-2
CREATE OR REPLACE FUNCTION f1 (i_v1 IN NUMBER)
    RETURN NUMBER
IS
BEGIN
    RETURN i_v1 + 1;
END;
/

 

Automatic SQL Transpiler 기능을 활성화하려면 sql_transpiler 파라미터를 ON으로 설정해야 합니다.

-- 2-1
SELECT name, value, default_value, description FROM v$parameter_valid_values WHERE name = 'sql_transpiler';

NAME           VALUE DEFAULT_VALUE DESCRIPTION
-------------- ----- ------------- ---------------------
sql_transpiler OFF   OFF           Enable SQL transpiler

1개의 행이 선택되었습니다.

-- 2-2
SELECT ordinal, value, isdefault FROM v$parameter_valid_values WHERE name = 'sql_transpiler';

ORDINAL VALUE ISDEFAULT
------- ----- ---------
      1 ON    FALSE
      2 OFF   TRUE

2 행이 선택되었습니다.

 

sql_transpiler 파라미터를 ON으로 설정하고 f1 함수를 사용한 쿼리를 수행하면 수행에 0.08초가 소요됩니다. Predicate Information 항목에서 f1 함수가 "C1" + 1 표현식으로 변환된 것을 확인할 수 있습니다. 

-- 3
ALTER SESSION SET sql_transpiler = 'ON';

SELECT /* TEST1 */ SUM (f1 (c1)) FROM t1 WHERE f1 (c1) > c2;

-------------------------------------------------------------------
| Id  | Operation          | Name | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |00:00:00.08 |    2078 |
|   1 |  SORT AGGREGATE    |      |      1 |00:00:00.08 |    2078 |
|*  2 |   TABLE ACCESS FULL| T1   |   1000K|00:00:00.04 |    2078 |
-------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("C2"<"C1"+1)

 

10053 트레이스에서 변환된 쿼리를 확인할 수 있습니다.

-- 4
Final query after transformations:******* UNPARSED QUERY IS *******
SELECT SUM("T1"."C1"+1) "SUM(F1(C1))" FROM "TUNA"."T1" "T1" WHERE "T1"."C2"<"T1"."C1"+1

 

sql_transpiler 파라미터를 OFF로 설정하고 동일한 쿼리를 수행하면 수행에 2.02초가 소요됩니다. Predicate Information 항목에서 함수가 표현식으로 변환되지 않은 것을 확인할 수 있습니다.

-- 5
ALTER SESSION SET sql_transpiler = 'OFF';

SELECT /* TEST2 */ SUM (f1 (c1)) FROM t1 WHERE f1 (c1) > c2;

-------------------------------------------------------------------
| Id  | Operation          | Name | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |00:00:02.02 |    2078 |
|   1 |  SORT AGGREGATE    |      |      1 |00:00:02.02 |    2078 |
|*  2 |   TABLE ACCESS FULL| T1   |   1000K|00:00:01.04 |    2078 |
-------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("C2"<"F1"("C1"))

 

21.3 버전에 추가된 스칼라 유형의 SQL Macro를 사용해도 단순 표현식을 반환하는 PL/SQL 함수를 SQL 표현식으로 변환할 수 있습니다. 아래와 같이 f2 함수를 생성하겠습니다.

-- 6
CREATE OR REPLACE FUNCTION f2 (i_v1 IN NUMBER)
    RETURN VARCHAR2 SQL_MACRO (SCALAR)
IS
BEGIN
    RETURN 'i_v1 + 1';
END;
/

 

f2 함수를 사용한 쿼리를 수행하면 수행에 0.08초가 소요됩니다. Predicate Information 항목에서 f1 함수가 "C1" + 1 표현식으로 변환된 것을 확인할 수 있습니다. 

-- 7
SELECT /* TEST3 */ SUM (f2 (c1)) FROM t1 WHERE f2 (c1) > c2;

-------------------------------------------------------------------
| Id  | Operation          | Name | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |00:00:00.08 |    2078 |
|   1 |  SORT AGGREGATE    |      |      1 |00:00:00.08 |    2078 |
|*  2 |   TABLE ACCESS FULL| T1   |   1000K|00:00:00.04 |    2078 |
-------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("C2"<"C1"+1)

 

10053 트레이스에서 변환된 쿼리를 확인할 수 있습니다.

-- 8
Final query after transformations:******* UNPARSED QUERY IS *******
SELECT SUM("T1"."C1"+1) "SUM(F2(C1))" FROM "TUNA"."T1" "T1" WHERE "T1"."C2"<"T1"."C1"+1
저작자표시 비영리 변경금지 (새창열림)
'Oracle/Performance' 카테고리의 다른 글
  • UNION ALL에 대한 Pushing Group By
  • UPDATE 문 SET 절 서브쿼리 Unnesting
  • 서브쿼리 팩토링 절과 log file sync 이벤트
  • V$SQL 뷰의 program_id, program_line# 칼럼
정희락
정희락
2007년부터 Oracle Database 성능 최적화에 주력해 왔으며, 현재 한국오라클 Engineered Systems Solution Engineering 팀에서 Solution Engineer로 근무하고 있습니다. 이 블로그는 개인적인 연구 목적으로 운영되며, Oracle 사의 공식 입장을 대변하지 않습니다.
  • 정희락
    TunA
    정희락
  • 전체
    오늘
    어제
    • 분류 전체보기 (194)
      • Oracle (166)
        • SQL (32)
        • PLSQL (10)
        • Performance (72)
        • Administration (36)
        • Installation (3)
        • Utilities (1)
        • JSON (8)
        • Vector (4)
      • Exadata (15)
      • SQL*Plus (2)
      • Linux (5)
      • Resources (6)
  • 블로그 메뉴

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

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

    12c
    19c
    21c
    23ai
    case study
  • 공지사항

  • 최근 글

  • 최근 댓글

  • 인기 글

  • 링크

    • Connor McDonald
    • Frits Hoogland
    • Jonathan Lewis
    • Julian Dontcheff
    • Julian Dyke
    • Kun Sun
    • Maria Colgan
    • Martin Bach
    • Mike Dietrich
    • Tanel Poder
  • hELLO· Designed By정상우.v4.10.0
정희락
Automatic SQL Transpiler
상단으로

티스토리툴바