사용자 정의 함수는 액세스 패스에 따라 수행 횟수가 달라질 수 있다. 관련 내용을 살펴보자.
테스트를 위해 아래와 같이 테이블과 함수를 생성하자.
-- 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번만 수행된다.
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번 출력되었다. 함수 결과가 필터 조건으로 사용되면 함수가 행의 수만큼 수행된다.
-- 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번만 출력된 것을 확인할 수 있다.
-- 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 |