안녕하세요 구루비에서 많은 도움을 받고 있는 개발자입니다.
merge문을 작성하다보니 조건에 따라 실행계획이 다르게 나오는부분이 있어 궁금한사항이 있어서 문의드립니다.
1번
merge into a using (select col, num from b where col = 'A') b on (a.col = b.col) when matched then update set a.num = b.num
2번
merge into a using (select col, num from b where col = 'A') b on (a.col = 'A') when matched then update set a.num = b.num
b에 들어가는 쿼리의 결과값은 반드시 col이 A만 나오게됩니다.
이때 on에 들어가는 조건에
1번과 같이 b의 결과값을 대입하였을때와
2번과 같이 값을 명시적으로 입력하였을때와 실행결과가 다르게 나옵니다.
(2번과 같이 값을 명시적으로 입력하였을때가 더 성능이 좋음)
어떻게 생각해보면 오라클입장에서는
b의 결과값이 어떤게 나올지 예측할 수 없으므로
a의 테이블에 전체 서치해야하므로 성능이 안나오는게 맞을듯한데
2번과 같이 쿼리를 작성하는게 더 좋은 성능을 내는게 맞다고 이해하면 될까요~?,
안녕하세요 마농님 실제 쿼리는 아래와 같습니다 (테이블 및 데이터는 일부 조작,,) 최종적으로 merge되는 데이터는 약 5천건 정도입니다. merge into A_202301 h using ( select intervalanstimestamp, site as site, distribution_agtid, sum(case when distribution_agtid is not null then 1 else 0 end) as offer, sum(case when agtid is not null then 1 else 0 end) as ans, sum(talktime) as talktime from ( select case when to_char(intervalanstimestamp, 'YYYY') = '0001' then intervaltimestamp else intervalanstimestamp end as intervalanstimestamp, site as site, distribution_agtid, agtid, talktime from B_202301 where ymd = '20230102' and site = 'A' union all select case when to_char(intervalanstimestamp, 'YYYY') = '0001' then intervaltimestamp else intervalanstimestamp end as intervalanstimestamp, userdata20 as site, distribution_agtid, agtid, talktime from B_202301 where ymd = '20230102' and userdata20 = 'A' ) group by intervalanstimestamp, site, distribution_agtid ) c on (h.ymd = '20230104' and h.site = c.site and h.timestamp = c.intervalanstimestamp and h.agtid = c.distribution_agtid) -- 성능이 떨어짐 on (h.ymd = '20230104' and h.site = 'A' and h.timestamp = c.intervalanstimestamp and h.agtid = c.distribution_agtid) -- 성능이 더 좋음 when matched then update set h.offer = c.offer, h.ans = c.ans, h.talktime = c.talktime, h.abd = c.offer - c.ans