함수의 호출과 속도 차이에 대해서... 0 8 1,607

by 야신 [PL/SQL] PLSQL 함수 [2013.07.22 11:56:52]


보통 조인으로 풀기 어려울 경우나 쿼리의 단순화를 위해 함수를 사용합니다.
그런데 그 함수가 여러개의 값을 리턴해야 할 경우 각각에 대한것을 함수로 만들게 되죠

예를 들면
품목아이디, 품목명, 품목코드 등..

SLELECT F_GET_ITEM_CODE(ITEM_ID )  AS ITEM_CODE
                 , F_GET_ITEM_DESC(ITEM_ID )  AS ITEM_DESC
                 , F_GET_ITEM_SPEC(ITEM_ID )  AS ITEM_SPEC
                , ITEM_ID
   FROM 판매이력;

이 함수가 좀 복잡하여 시간을 소요한다고 할때
위와 같이 사용하는 것이 속도면에서 나은가요? 아니면 아래와 같이 사용하는 것이 나을까요?

SELECT SUBSTR( ITEM_NAME_DESC, 1,10 )        AS ITEM_NAME
               , SUBSTR( ITEM_NAME_DESC, 11,10 )      AS ITEM_DESC
               , SUBSTR( ITEM_NAME_DESC, 13,10 )      AS ITEM_SPEC
              , ITEM_ID
   FROM (
SLELECT /*+ NO_MERGE */ 
                F_GET_ITEM_CODE_DESC(ITEM_ID ) AS ITEM_NAME_DESC
              , ITEM_ID  
   FROM 판매이력);
※ 마농님의 조언에 따라 한번만 호출하는 효과를 얻기 위해 위와 no_merge 힌트를 추가하였습니다.
no_merge 를 사용하지 않으면 1 과 똑같습니다...



제 3의 방법으로는 PIPE FUNCTION 이 있습니다. 여러값을 조인한것처럼 한번에 받아 올수 있죠.

SELECT  T.ITEM_NAME    AS ITEM_NAME
               , T.ITEM_DESC      AS ITEM_DESC
              , T.ITEM_SPEC       AS ITEM_SPEC
              , ITEM_ID
   FROM 판매이력
 LFET JOIN TABLE(TAB_FUNC(ITEM_ID)) T
 ON  판매이력.ITEM_ID = T.ITEM_ID;


각각마다 장단점이 있는데
1번 방법은 가져오는 함수가 완전히 구분되어 있어 명확하다는 것이고, 속도상은 좀 불리하죠. 여러번 함수를 호출해야 하니.
2번 방법은 함수에서 여러개의 값을 구분자로 묶어 하나로 호출한 뒤 뒤에서 잘라써야 한는 불편함이 있지만
호출은 한번만 할것 같아서 속도면에서 1번 보다 나아 보이고요. ( 단 no_merge 힌트 추가시)
3.번 방법은 다중으로 리턴값을 받을 수 있어 편리할 수 있지만  펑션(1,2) 보다 속도가 약간 떨어지는 듯 하더군요.

여러분은 어떤 방법을 선호하시는지?

PS) 예제로 간략하게 만들었으니 약간의 오류는 무시하여 주세용 ^^
by 부쉬맨 [2013.07.22 12:49:34]
상황에맞게쓰는게...
예전테스트
http://wiki.gurubee.net/pages/viewpage.action?pageId=26738860

by 야신 [2013.07.22 14:40:14]
함수에서 가져오는 값이 여러테이블에서 우선순위별로 찾아서 가져오다 보니 시간이 많이 걸리는데
테스트시 두개의 함수를 쓰개 되면 파이프 function 과 비슷하고 그 이상을 쓰니 파이프 보니 느려지네요.

by 용근님 [2013.07.22 13:00:26]

1 /2  번은 별로 고민하게 만드는 부분은 아닌듯 개인취향이 더 강할듯

3번으로 하실꺼면 모든 게시판성 쿼리를 패키지에 담아서 Table Function 형태로 만드시는게.

한놈만 저런다면 통일성이 없어서 좀

by 야신 [2013.07.22 14:41:24]
개인의 취향으로 하기에는 위에서 속도에 대해 엄청 민감하게 반응해서요..
몇백만간 데이타를 다루다 보니...DW 랑 비슷합니다. ㅠㅠ

by 우리집아찌 [2013.07.22 14:20:39]

파이프라인드 테이블 펑션은 처음보는데 재밌네요..

by 야신 [2013.07.22 14:42:23]
한번 써 보시면 나름대로 매력적입니다.
다만 ANSI SQL 로 써야 하는 부담이 살짝...

by 마농 [2013.07.22 14:48:31]

성능에 중점을 둔다면
함수 사용 안하고 ONE SQL 로 바꿀 수 있으면 좋구요.
함수를 사용해야 한다면
1번보다는 2번이 빠르겠죠.
단, 위와 같이 하시면 효과 없구요. 1번과 성능 같습니다.
2번이 효과를 거두려면 NO_MERGE 힌트와 함께 사용하셔야 합니다.
그리고 1번이든 2번이든 함수 내부 로직 최적화가 선행되어야 하겠지요.
함수 내부에 비효율은 없는지 확인해서 효율적으로 바꿔야 겠습니다.


by 야신 [2013.07.22 14:53:29]
1 SQL 로 바꾸기 싶지만 업무로직 상 힘들어서 함수로 구현되어 있습니다.
이전의 방식이 1번과 같은 방식으로 되어 있는데
이번에 통합구축을 하면서 속도 향상을 꾀하고 있어서 고민 하고 있네요.
마농님의 조언 감사합니다.
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입