여러개 테이블 조인시 where 조건에 따른 실행계획 변화에 대한 문의 0 4 602

by 멀미나 [Oracle Tuning] [2019.05.17 10:14:46]



안녕하세요 

테이블 조인시 where 조건에 따른 실행계획 변화에 대한 질문을 드립니다

아래 쿼리에 대한 실행계획은 첨부파일1 '조건전 실행계획' 처럼 표시 되며 1초 미만으로 조회결과가 나옵니다.

그런데 주석처리 되어있는 AND M1.NACC200_BILL_STS_CD = '60' 조건을 추가하면 실행계획도 변하고 조회 시간도 10분정도로 증가합니다.

M1.NACC200_BILL_STS_CD = '60' 조건을 확인하기 위한 랜덤액세스 때문일까 라는 생각이 들어 인덱스를 추가해 보았지만 실행계획의 큰 틀은 변하지 않았습니다. 

힌트 추가등을 통해 M1.NACC200_BILL_STS_CD = '60' 조건 추가 전의 실행계획 형태로 사용이 가능한지 아니면 전체적인 접근 법이 잘못된 것인지 판단이 안되서 문의 드립니다. 

SELECT
/*+ORDERED */
D1.NACC210_ACT_CD            AS ACT_CD,
D1.NACC210_CAMPUS_CD         AS CAMPUS_CD,
D1.NACC210_ACC_DIV_CD        AS ACC_DIV_CD,
C1.NACC050_DC_DIV_CD AS DC_DIV_CD,
DECODE(D1.NACC210_DC_DIV_CD, 'D', D1.NACC210_AMT, 0)  AS DR_AMT,
DECODE(D1.NACC210_DC_DIV_CD, 'C', D1.NACC210_AMT, 0)  AS CR_AMT
FROM NACC050TL C1, NACC210TL D1, NACC200TL M1
WHERE 1=1
AND C1.NACC050_ACC_YEAR < '2018'
AND C1.NACC050_ACC_YEAR  >= '2014'
AND DECODE(C1.NACC050_ACC_UNIT_CD, '03', '16', C1.NACC050_ACC_UNIT_CD) IN (SELECT COLUMN_VALUE FROM TABLE(f_nacc_split_array('01,02,03,04,05,06'',')))
AND SUBSTR(C1.NACC050_ACT_CD, 1, 4) IN ('1123', '2141')
AND C1.NACC050_ACT_CD NOT IN ('1123007', '2141003')
AND D1.NACC210_ACC_YEAR    = C1.NACC050_ACC_YEAR
AND D1.NACC210_ACC_UNIT_CD = C1.NACC050_ACC_UNIT_CD
AND D1.NACC210_CAMPUS_CD   LIKE :as_p_campus_cd_param || '%'
AND D1.NACC210_ACC_DIV_CD LIKE :as_p_acc_div_cd_param || '%'
AND D1.NACC210_ACT_CD      = C1.NACC050_ACT_CD
AND M1.NACC200_BILL_NO     = D1.NACC210_BILL_NO
-- AND M1.NACC200_BILL_STS_CD = '60'
AND 'N' =F_NACC_IN_TRAD_YN(:as_p_campus_cd_param,:as_p_setac_grp_div_cd_param,:as_p_acc_div_cd_param,
D1.NACC210_INTRD_CAMPUS_CD, D1.NACC210_INTRD_ACC_UNIT_CD, D1.NACC210_INTRD_ACC_DIV_CD)

 

by 부쉬맨 [2019.05.17 10:26:39]

해당쿼리만 봣을때 M1 테이블의 대상컬럼이 조회절에 들어가지않으니깐

fileter조건으로 빼서 exsits 형태로 빼시는게좋아보입니다.

조건절 빼기전은 풀로탄거같고

조건절 추가하고는 인덱스를 타면서 불필요한 NL작업진행

 


by 마농 [2019.05.17 10:40:23]

1번 실행계획은 m1 테이블을 아예 안 읽네요.
 - 읽을 필요가 없었던 거죠.
 - 참조 제약이 걸려 있고 사용되는 컬럼도 없어서 그렇구요.
2번에서는
 - m1 의 컬럼에 조건을 줘야하니 테이블을 읽어야만 하게 된거죠.
 - 그러면서 hash unique 의 실행 시기도 뒤로 미뤄졌네요.
Ordered 힌트가 있는데?
 - 이게 최선의 선택인지?
 - 1번에 최적화된 힌트라면? 2번에서는 힌트 빼야 할 듯.


by 멀미나 [2019.05.21 09:36:43]


답변 너무 감사드립니다. 조인에만 너무 집착해서 다른 접근법은 고려를 하지 못했네요 

한가지만 더 여쭤보자면 ..

마농님 답변 내용 중 m1 조건이 추가되면서 hash unique 실행 시기가 뒤로 미뤄진 이유가 뭔지 궁금합니다.

hash unique 와 view view 실행계획은 c1의 where 조건의 서브쿼리와 상관있는 것이고

ordered를 힌트를 통해 가장 먼저 처리가 되는 것으로 이해를 했습니다.

그래서 m1의 변화와는 상관없이 계속 가장 먼저 처리가 될 것으로 생각을 했는데 where 조건 추가 후 실행계획이 확 변해서... 그 이유가 궁금합니다.

아 그리고 ordered 힌트를 쓴 이유는 c1의 조건으로 f_nacc_split_arrary 함수가 들어간 서브쿼리를 쓰는데 이게 힌트를 안주면 실행순서가 뒤로 빠지면서 속도가 안 나왔습니다.

c1의 결과가 백단위이고 d1은 십만단위라서 저런 순서로 계획을 했습니다. 


by 마농 [2019.05.21 09:51:16]

실행계획이 확 바뀌었다고 하셨지만..
m1 을 읽는 부분이 추가 된 것 외에는 실행 순서는 그대로 인듯 한데요?
hash unique 가 왜 뒤로 미뤄졌는지는 모르겠네요. 왜 hash unique 가 필요한지도 모르겠구요.
SELECT column_value 부분에 DISTINCT 를 추가해 보는건 어떨까요?
IN 서브쿼리가 아닌 조인으로 풀어보는것은 어떨까요?

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입