모 프로젝트에서 개발자들로부터  튜닝 요청받은 쿼리 중에서  가장 많은  패턴중 하나가


아래와 같이  select target 절에   사용자 함수를 사용한 경우임.  


사용자 함수를 함부로 사용하지 못하도록 프로젝트 시작시 rule 을 만들어야 하는 게 아닌가 할 정도로  SQL 성능 저하의 주요 원인 중 하나였음.


DB : tibero


1. 유형

  사용자 함수를 아래와 같이 select 절에 사용하는 경우임.

select

             ....

           ,  JISA_NAME( A.JISA_code )   지사이름

             ....

from   자금지원이력 A

where   A.기간 between  sysdate -10/24/60  and  sysdate

group by  A.region



2. 병목 원인

  * 사용자 함수는  recursive call 로  느림

  * 최종 결과 건수에 상관없이 조건절에 부합하는 전체 레코드 건수 만큼 함수 호출이 발생함.

 


3. 튜닝방법

  1)   최종 결과 집합에서만  함수 호출이 일어나도록 하는 방법

     select  

                ...

               , JISA_NAME( jisa_code )  지사이름

     from (

                  select     /*+ no_merge */

                              A.region

                            , A.jisa_code

                            ....

                  from  자금지원이력 A

                 where   A.기간 between  sysdate -10/24/60  and  sysdate

                 group by  A.region

             )


 2)  decode  함수 또는 case 문으로 변환

       함수 로직이 계산식이 주일 경우

 3)  함수를 풀어서   inner join 또는 outer join 으로 변경

       select

                  B.JISA_NAME

       from 자금지원이력 A,  지사이름 B

       where  A.jisa_code = B.jisa_code

      and   A.기간 between  sysdate -10/24/60  and  sysdate

      group by  A.region


 4)  스칼라 서브쿼리 캐싱 효과를 이용

     oracle 은  select 함수명 from dual  구문으로 호출하면 서브쿼리 캐싱 효과를 얻을 수 있음.  

     tibero 의 경우는  from dual 구문을 사용하지 않아도 plan 상으로는  sub쿼리 caching 표시가 되나 실제도 캐싱되는지는 확실하지 않음.

     oracle 과 동일하게 구현되었다면   from dual 구문을 사용하면  성능 효과를 볼 수 있을 듯 하다.

     

     함수의 결과값의 종류가 적을 때 사용가능하다.

     from (

                select  /*+ NO_MERGE */

                       ( select JISA_NAME(A.JISA_code ) from dual ) 지사이름

       .....

 5) Deterministic 함수로 캐싱 효과

     오라클에서 지원함.

     함수 생성시  deterministic 구문 명시하면 서브쿼리 캐싱 효과를 낼 수 있음.


    함수 생성시   

      create   or replace funciton JISA_NAME( p_jisacode  varchar )  return varchar  DETERMINISTIC 

         ...    




'DBMS > SQL(쿼리튜닝)' 카테고리의 다른 글

선택적 검색 조건에 사용할 수 있는 기법  (0) 2018.05.01

A. OR 조건을 사용하는 경우

주의 : 이 방식은 항상 full scan 으로 처리되므로 주의해야 한다


B. LIKE 연산지를사용하는 경우


인덱스 사용이 가능하지만 시용자가 :isu_cd 값을 입력하지 않았을 때  table  full Scan이 유리한데도 인덱스를 사용하게 되므로 성능이 나빠질 수 있다.



C. NVL 함수를 시용하는 경우




D. Decode 함수를 사용하는 경우


조건 칼럼이 NOT NULL 일 경우에만 사용 가능하다  NULL 허용일 경우 결과가 달라질 수 있다.
:isu_cd 가   없으면  isu_cd = isu_cd가 되는 데   null 인 경우 항상 false 이므로 null 인 레코드는 제외하고 결과가 리턴된다.

E. UNION ALL 을 사용하는 경우




null 값을 허용하고 인덱스 엑세스 조건이 의미있는 경우라면 union all  사용을 권장함.


'DBMS > SQL(쿼리튜닝)' 카테고리의 다른 글

함수 부하가 병목인 쿼리 튜팅  (0) 2018.08.04

+ Recent posts