사용자 정의 함수는 액세스 패스에 따라 수행 횟수가 달라질 수 있다. 관련 내용을 살펴보자.
테스트를 위해 아래와 같이 테이블과 함수를 생성하자.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
-- 1 DROP TABLE t1 PURGE; CREATE TABLE t1 AS SELECT LEVEL AS c1, LEVEL AS c2 FROM DUAL CONNECT BY LEVEL <= 10; CREATE INDEX t1_x1 on t1 (c1); CREATE OR REPLACE FUNCTION f1 RETURN NUMBER IS BEGIN DBMS_OUTPUT.PUT_LINE ( 'X' ); RETURN 1; END ; / |
아래 쿼리는 X가 1번 출력되었다. 함수 결과가 액세스 조건으로 사용되면 함수가 1번만 수행된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
SET SERVEROUTPUT ON -- 1 SELECT * FROM t1 WHERE c1 = f1; ----------------------------------------------------- | Id | Operation | Name | ----------------------------------------------------- | 0 | SELECT STATEMENT | | | 1 | TABLE ACCESS BY INDEX ROWID BATCHED| T1 | |* 2 | INDEX RANGE SCAN | T1_X1 | ----------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access( "C1" = "F1" ()) C1 C2 -- -- 1 1 1개의 행이 선택되었습니다. X |
아래 쿼리는 X가 10번 출력되었다. 함수 결과가 필터 조건으로 사용되면 함수가 행의 수만큼 수행된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
-- 2 SELECT * FROM t1 WHERE c2 = f1; ---------------------------------- | Id | Operation | Name | ---------------------------------- | 0 | SELECT STATEMENT | | |* 1 | TABLE ACCESS FULL | T1 | ---------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter( "C2" = "F1" ()) C1 C2 -- -- 1 1 1개의 행이 선택되었습니다. X X X X X X X X X X |
함수 결과가 필터 조건으로 사용될 경우 서브 쿼리를 통해 함수의 수행 횟수를 감소시킬 수 있다. 아래 쿼리는 함수에 서브 쿼리를 사용했다. X가 1번만 출력된 것을 확인할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
-- 3 SELECT * FROM t1 WHERE c2 = ( SELECT f1 FROM DUAL); ---------------------------------- | Id | Operation | Name | ---------------------------------- | 0 | SELECT STATEMENT | | |* 1 | TABLE ACCESS FULL | T1 | | 2 | FAST DUAL | | ---------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter( "C2" = ( SELECT "F1" () FROM "SYS" . "DUAL" "DUAL" )) C1 C2 -- -- 1 1 1개의 행이 선택되었습니다. X |
'Oracle > Tuning' 카테고리의 다른 글
TIMESTAMP 인덱스 - Right-Growing 경합 #1 (0) | 2019.02.28 |
---|---|
CLOB #6 - 블록 I/O (0) | 2019.02.27 |
SQL Patch (0) | 2019.01.09 |
SQL Profile (0) | 2019.01.09 |
다중 행 다중 열 스칼라 서브 쿼리의 부분 범위 처리 (0) | 2019.01.09 |