SQL 중 최종 추출 결과가 적은 경우에는, Function의 수행위치를 변경하여 과다 수행되는 성능 문제를 해결 할 수 있다.
예를들면,
select z.*
(select
empCnt (e.title) empCnt ,
deptCnt (d.title) deptCnt,
...
from emp e inner join dept d ON e.deptno = d.deptno
where ... ) z
order by rownum <= 3
만약 emp 와 dept 의 inner join rows가 4만건이라면 해당 함수도 4만횟수를 수행하여 쿼리 I/O 상에서는 문제가 없겟지만
함수 I/O 상에서 문제가 크게 발생된다 왜냐하면 함수를 굳이 4만번 수행하지 않고 rownum 3회만 수행하게 할 수 있기 때문이다.
select x.*
, empCnt(x.eTitle) empCnt
, deptCnt(x.dTitle) deptCnt
from (
select z.*
from (
select
e.title eTitle ,
d.title dTitle ,
...
from emp e inner join dept d ON e.deptno = d.deptno
where ... ) z
order by rownum <= 3
) x
위와 같이 쿼리를 수행하면 과다 수행 되지않고 3row를 뽑은뒤 함수가 3번만 수행 되게 되어진다.
하지만 SQL의 최종 추출 결과가 많은 경우에는, Function 의 수행 위치를 바꾸는 것만으로 성능을 개선하기는 힘들다.
Main SQL 에서 추출한 데이터 중 Function을 수행하는 입력값의 종류가 적은 경우 (Distinct rows가 적은경우) 스칼라 서브쿼리에서 Function을 수행하도록 변경하면, Multi Buffer 를 이용해 성능을 개선 시킬 수 있다.
select
jisaname( gr. jisacode1, '00', sysdate ) jisaname1 ,
jisaname( gr.jisacode1, gr.jisacode2, sysdate ) jisaname2,
groupname( gr.parent_groupno ) parent_groupname ,
groupname ( gr.groupno ) groupname ,
...
from t_member mem inner join t_group gr ON gr.groupno = mem.groupno
where ...
해당 쿼리의 함수별 추출 데이터 건수가 4,708 * 4 = 18,832 건이라 하면
select
(SELECT jisaname( gr. jisacode1, '00', sysdate ) FROM DUAL) jisaname1 ,
(SELECT jisaname( gr.jisacode1, gr.jisacode2, sysdate ) FROM DUAL) jisaname2,
(SELECT groupname( gr.parent_groupno ) FROM DUAL) parent_groupname ,
(SELECT groupname ( gr.groupno ) FROM DUAL) groupname ,
...
from t_member mem inner join t_group gr ON gr.groupno = mem.groupno
where ...
jisaname() 은 2번, groupname()은 총 2,213번으로 수행건이 줄어들었다.
gr.jisacode1, 과 gr.jisacode2가 모두 동일한 값을 가지고 있어 스칼라 서브쿼리에서 수행되도록 변경한 경우,
최초 1회씩만 수행하고 나머지는 Cache에서 결과 값을 가져 올 수 있었기 때문이다.
이와같이 입력 값에 대응하는 값의 종류가 다양하지 않아, 같은 입력 값에 대한 결과 값이 항상 동일하다면,
Function 은 스칼라 서브쿼리에서 수행하도록 변경하여 Function 수행에 의한 부하를 감소시켜야 한다.
'Database > SQL Tuning' 카테고리의 다른 글
[Join] NL / HASH / MERGE 조인 매커니즘 (0) | 2017.04.03 |
---|---|
ROWNUM 의 이해와 성능 관리 (0) | 2015.09.03 |
[Oracle] Function 내부작동 및 Nasted Loops Join / Hash Join (0) | 2015.08.25 |
Pipelined Table & Table Function (0) | 2015.08.25 |
[Merge] Update 컬럼은 On 절에 사용 할수 없을 때 (0) | 2015.08.24 |