오라클 쿼리 튜닝 문의. 0 4 4,393

by 통쓰 [Oracle Tuning] [2024.03.27 14:09:35]


실행계획.png (127,381Bytes)

안녕하세요. 아래 쿼리가 데이터가 많아질수록 너무 느려져서 튜닝을 하려고하는데, 어디부터 손을 봐야할지 
감이 안와서...확인 좀 부탁드립니다....
최대한 줄이기는 했는데...아직도 1분이 넘게 걸리네요..

SHPDR(5천건정도) 이 테이블이 DISTINCT를 할때 10초정도 걸리는데, 그룹바이로 바꿔도 2초정도 차이나는거같습니다...
			SELECT   
			    S.WORKNM||SR.CARNUM||S.SDIFKY||SR.SHIPSQ  AS SEARCHKEY,  
			    SDIFKY AS SDIFKY,   
			    SDIFIT AS SDIFIT,         
			    S.LOCASR AS LOCASR ,   
			    LM.SHORTX AS LOCAKYNM,  
			    S.SKUKEY AS SKUKEY,  
			    SM.DESC01 AS DESC01,  
			    SM.DESC02 AS DESC02,  
			    DECODE(SUM(S.QTCOMP), 0, SUM(S.QTTAOR-S.QTCOMP) , SUM(S.QTTAOR) ) QTTAOR,  
			    SUM(S.QTTAOR-S.QTCOMP) AS QTCOMP,  
			    NVL(SM.QTYSTD,0) AS PLIQTY,  
			    NVL(SM.QTDUOM,0) AS BXIQTY,  
			    NVL(  TRUNC( SUM(S.QTTAOR-S.QTCOMP) / DECODE(SM.QTDUOM, 0, NULL,SM.QTDUOM) ) ,0) AS BOXQTY,         
			    NVL(  TRUNC( SUM(S.QTTAOR-S.QTCOMP) / DECODE(SM.QTYSTD, 0, NULL,SM.QTYSTD) ) ,0) AS PLTQTY,         
			    NVL(MOD( SUM(S.QTTAOR) , DECODE(SM.QTDUOM, NULL,0,SM.QTDUOM)),0) AS REMQTY,  
			    NVL(SM.GRSWGT,0) * (SUM(S.QTTAOR-S.QTCOMP))  AS GRSWGT,  
			    NVL(SM.GRSWGT,0)   AS GRSWGTCNT,  
			    DECODE(SUM(S.QTTAOR-S.QTCOMP) , 0 , 'FPC',  'NEW') STATIT,  
			    S.TASKKY  AS TASKKY,  
			    S.TASKIT  AS TASKIT  
			FROM TASDH  
	  INNER JOIN TASDI S  
	          ON TASDH.TASKKY = S.TASKKY  
       LEFT JOIN ( 
				    SELECT L.LOCAKY, Z.SHORTX  
				      FROM ZONMA Z  
			    INNER JOIN LOCMA L  
				        ON L.WAREKY = Z.WAREKY AND L.TKZONE = Z.ZONEKY 
				) LM  
              ON LM.LOCAKY = S.LOCASR  
      INNER JOIN SKUMA SM  
              ON SM.OWNRKY = S.OWNRKY AND SM.SKUKEY = S.SKUKEY  
       LEFT JOIN ( 
			    SELECT DISTINCT SHPOKY
			         , SHPOIT
			         , ARRIVA
			         , CARDAT
			         , CARNUM
			         , SHIPSQ
			         , SORTSQ
			         , DRIVER
			         , RECAYN
			         , TASKKY  
			      FROM SHPDR   
			     WHERE RECAYN = 'N'   
			       AND TASKKY != ' '  
			       AND CARNUM != ' ' 
			    )  SR  
               ON SR.SHPOKY = S.SHPOKY AND SR.SHPOIT = S.SHPOIT                
        LEFT JOIN SHPDI  
               ON SHPDI.SHPOKY = S.SHPOKY AND SHPDI.SHPOIT = S.SHPOIT  
        LEFT JOIN SHPDH 
               ON SHPDH.SHPOKY = S.SHPOKY  
            WHERE 1=1  
			  AND SR.TASKKY != ' '   
		      AND  S.LOCASR != 'DOCLOC'  
			  AND  SHPDH.DRELIN = 'V'  
              AND (  (  ( TASDH.DOCDAT = '20240321' )  )  AND (  ( SR.CARDAT = '20240322' )  )  AND (  ( SR.SHIPSQ = '101' )  OR  ( SR.SHIPSQ = '102' )  )  AND (  ( TASDH.TASOTY = '210' )  OR  ( TASDH.TASOTY = '208' )  )  )   
			  AND SDIFKY = NVL(' ', ' ')  
			  AND SDIFIT = NVL(' ', ' ')  
			  AND LOCASR = '1J01101'  
			  AND S.SKUKEY = '103634'  
			  AND S.WORKNM||SR.CARNUM||S.SDIFKY||SR.SHIPSQ||SR.CARDAT = '제주하치장C002 10220240322'  
			  AND TASDH.DOCDAT > TO_CHAR(SYSDATE - 60, 'YYYYMMDD')  
			  AND SHPDH.DOCDAT > TO_CHAR(SYSDATE - 60, 'YYYYMMDD')  
         GROUP BY S.WORKNM||SR.CARNUM||S.SDIFKY||SR.SHIPSQ,  
		          S.LOCASR,   
		          SDIFKY,  
		          SDIFIT,  
		          S.SKUKEY,  
		          NVL(SM.QTYSTD,0),  
		          NVL(SM.QTDUOM,0),  
		          NVL(SM.GRSWGT,0),  
		          SM.QTYSTD,  
		          SM.QTDUOM,  
		          SM.GRSWGT,  
		          LM.SHORTX,  
		          SM.DESC01,  
		          SM.DESC02,  
		          S.TASKKY,  
		          S.TASKIT  
	    ORDER BY S.SKUKEY

 

by 마농 [2024.03.28 10:02:28]

1. 아우터 조인을 하면서 where 조건을 주는 것은
 - 아우터 조인 하나마나한 이너조인과 같습니다.
 - sr 과 shpdh 에 대한 아우터 조인은 이너조인으로 바꾸세요.
2. shpdi 에 대한 아우터 조인을 하는데?
 - 해당 테이블의 항목을 전혀 사용하지 않고 있네요.
 - 조인 자체가 불필요해 보입니다.
3. 컬럼을 이어 붙여서 조건값과 비교하지 말고
 - 조건값을 잘라서 각각 비교하세요.
4. DECODE(SUM(s.qtcomp), 0, SUM(s.qttaor - s.qtcomp), SUM(s.qttaor)) qttaor
 - 이 구문이 의미가 있는 건지 모르겠네요?
 - 내 생각에는 단순 SUM(s.qttaor) 만 해도 같은 의미일 것 같은데요?
5. Group by 항목으로 
 - NVL(sm.qtystd, 0) 과 sm.qtystd 이 동시에 있는데?
 - sm.qtystd 하나만 있어도 됩니다.
6. 복잡하게 작성한 이 조건은
- AND (  (  ( TASDH.DOCDAT = '20240321' )  )  AND (  ( SR.CARDAT = '20240322' )  )  AND (  ( SR.SHIPSQ = '101' )  OR  ( SR.SHIPSQ = '102' )  )  AND (  ( TASDH.TASOTY = '210' )  OR  ( TASDH.TASOTY = '208' )  )  )   
- 다음과 같이 단순화 할 수 있습니다.
- AND tasdh.docdat = '20240321'
- AND sr.cardat = '20240322'
- AND sr.shipsq IN ('101', '102')
- AND tasdh.tasoty IN ('210', '208')
7. sr 에 대한 메인의 조건들은
- 인라인 뷰 안으로 넣으시면 됩니다.
8. 컬럼명과 동일하게 별칭을 주고 있내요?
- 소스만 복잡해 집니다.
9. Distinct 가 왜 필요할까요?
- 항목들이 많은데 사용되는 항목이 아닌 것들도 있네요?


by 통쓰 [2024.03.28 10:06:48]

마농님 감사합니다. 이대로 다시 수정해보겠습니다.


by 마농 [2024.03.28 14:26:42]

10. skukey 는 한가지 값 뿐인데
 - 이 항목으로 정렬은 무의미하고, 정렬은 불필요 합니다.


by 통쓰 [2024.03.28 15:05:13]

감사합니다!! 많은 공부가 되었습니다!! 속도도 훨씐 빨라졌구요!!

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