with절 임시테이블을 이용한 조회 시 속도 저하 3

by 기봉이 [PL/SQL] [2022.02.28 18:36:24]


조회쿼리 입니다.

WITH 테이블 자체 조회시에는 속도에 문제가 없으나,

임시테이블을 이용하여 아래처럼 조회를 하면 속도저하가 너무 심합니다.

 

WITH TB( ..중략..)

SELECT RANK, 
    ,SUM( CASE WHEN A.ATYPE = '1' AND A.ENTRY_YN = 'Y' THEN A.AMT END ) AS doorA
    ,SUM( CASE WHEN A.ATYPE = '1' AND A.ENTRY_YN = 'N' THEN A.AMT END ) AS doorB
    ,SUM( CASE WHEN A.BTYPE = '2' AND A.ENTRY_YN = 'Y' THEN A.AMT END ) AS moldA
    ,SUM( CASE WHEN A.BTYPE = '2' AND A.ENTRY_YN = 'N' THEN A.AMT END ) AS moldB
    ,SUM( CASE WHEN A.BTYPE = '3' AND A.ENTRY_YN = 'Y' THEN A.AMT END ) AS pvcA
    ,SUM( CASE WHEN A.BTYPE = '3' AND A.ENTRY_YN = 'N' THEN A.AMT END ) AS pvcB
    ,SUM( CASE WHEN A.BTYPE = '4' AND A.ENTRY_YN = 'Y' THEN A.AMT END ) AS floorA
    ,SUM( CASE WHEN A.BTYPE = '4' AND A.ENTRY_YN = 'N' THEN A.AMT END ) AS floorB
    ,SUM( CASE WHEN A.BTYPE = '5' AND A.ENTRY_YN = 'Y' THEN A.AMT END ) AS bigA
    ,SUM( CASE WHEN A.BTYPE = '5' AND A.ENTRY_YN = 'N' THEN A.AMT END ) AS bigB
    ,SUM( CASE WHEN A.BTYPE = '6' AND A.ENTRY_YN = 'Y' THEN A.AMT END ) AS wallA
    ,SUM( CASE WHEN A.BTYPE = '6' AND A.ENTRY_YN = 'N' THEN A.AMT END ) AS wallB
    ,SUM( CASE WHEN A.BTYPE = '7' AND A.ENTRY_YN = 'Y' THEN A.AMT END ) AS artA
    ,SUM( CASE WHEN A.BTYPE = '7' AND A.ENTRY_YN = 'N' THEN A.AMT END ) AS artB

    ,SUM(A.AMT) AS total
FROM TB A
WHERE 1 = 1
GROUP BY RANK;

 ,SUM( CASE WHEN A.ATYPE = '1' AND A.ENTRY_YN = 'Y' THEN A.AMT END ) AS doorA  로 검색해오는 컬럼 속도를 향상시킬 쿼리가 있을까요..?

 

by 마농 [2022.02.28 18:53:13]

With 바깥쪽은 문제 없어 보입니다. With 안쪽 쿼리도 보여주세요.


by 기봉이 [2022.02.28 19:03:58]

WITH 절입니다~!

WITH TB AS (
            SELECT
                  B.RANK,PB.CUST  
                  ,FS02_GET_CUST_NM(PB.CUST, TO_CHAR(SYSDATE,'YYYYMMDD')) AS CUST_NM
                  ,PC.MNG_DEPT
                  ,FC00_GET_DEPT_NM(PC.MNG_DEPT, PB.YYMM||'01') AS MNG_DEPT_NM
                  ,PC.MNG_EMP
                  ,FC00_GET_EMP_NM(PC.MNG_EMP, PB.YYMM||'01') AS MNG_EMP_NM
                  ,FC00_GET_EMP_RANK(PC.MNG_EMP, PB.YYMM||'01') AS EMP_DEPT
                  ,PB.YYMM
                  ,PB.LTYPE
                  ,PB.MTYPE
                  ,PB.STYPE
                  ,PB.ENTRY_YN
                  ,PB.TYPE
                  ,PB.AMT
            FROM(
                    SELECT DENSE_RANK() OVER ( ORDER BY PP.CUST ) AS RANK
                                ,PP.CUST
                                ,PP.YYMM
                                ,SS.CODE
                                ,SS.LTYPE
                                ,SS.MTYPE
                                ,SS.STYPE
                                ,CASE WHEN NVL(PE.ENTRY_TYPE,'A') IN ('C','D') THEN 'Y' ELSE 'N' END ENTRY_YN
                                ,PP.TYPE
                         ,SUM(PP.AMT) AS AMT
                    FROM TS01_PROJ_SUMMARY PP
                    JOIN (
                           SELECT  DISTINCT CODE, REMARK3 AS LTYPE, REMARK4 AS MTYPE, REMARK5 AS STYPE
                           --SELECT  CODE, REMARK3 AS LTYPE, REMARK4 AS MTYPE, REMARK5 AS STYPE
                             FROM  TC00_CODE_LIST
                            WHERE  1 = 1
                              AND  CODE_GROUP = 'SALES_TYPE'
                              AND  TO_CHAR(SYSDATE, 'YYYYMMDD') BETWEEN FROM_DATE AND TO_DATE
                              AND  DEL_DATE IS NULL
                         )SS
                      ON PP.SALES_TYPE = SS.CODE
                    JOIN TS01_PROJ_CONST_ENTRY PE
                      ON PP.CUST = PE.CUST
                     AND PP.SALES_TYPE = PE.SALES_TYPE
                   WHERE 1=1
                     AND PP.TYPE <> 'A'
                GROUP BY PP.CUST, PP.YYMM, SS.CODE, SS.LTYPE, SS.MTYPE, SS.STYPE, NVL(PE.ENTRY_TYPE,'A'), PP.TYPE

                UNION ALL

                    SELECT DENSE_RANK() OVER ( ORDER BY PP.CUST ) AS RANK
                             ,PP.CUST
                             ,PP.YYMM
                             ,SS.PTYPE
                             ,SS.LTYPE
                             ,SS.ATYPE
                             ,SS.BTYPE
                             ,'N' AS ENTRY_YN
                             ,PP.TYPE
                             ,SUM(PP.AMT) AS AMT
                    FROM TB_SUMMARY PP
                    JOIN (                                     
                          SELECT  DISTINCT REMARK6 AS PTYPE, REMARK3 AS LTYPE, REMARK4 AS MTYPE, REMARK5 AS STYPE
                            FROM  TC00_CODE_LIST
                           WHERE  1 = 1
                             AND  CODE_GROUP = 'SALES_TYPE'
                             AND  TO_CHAR(SYSDATE, 'YYYYMMDD') BETWEEN FROM_DATE AND TO_DATE
                             AND  DEL_DATE IS NULL
                        )SS
                      ON PP.SALES_TYPE = SS.PTYPE
                   WHERE 1=1
                    AND PP.TYPE = 'A'
                   GROUP BY PP.CUST, PP.YYMM, SS.PTYPE, SS.LTYPE, SS.MTYPE, SS.STYPE, TYPE
                )PB
             JOIN TS01_PROJ_CONST_RANK PC
               ON PB.CUST = PC.S_CUST
             JOIN(
                  SELECT RANK, CUST
                    FROM TS01_PROJ_CONST_RANK
                   WHERE YY = TO_CHAR(TO_DATE(:pToDate, 'YYYYMM'), 'YYYY')
                   GROUP BY RANK, CUST
                   ORDER BY RANK
                 ) B
               ON PB.CUST = B.CUST
              AND PC.YY = TO_CHAR(TO_DATE(:toDate, 'YYYYMM'), 'YYYY')
            WHERE 1 = 1
              AND YYMM BETWEEN :fromDate AND :toDate
              )


by 마농 [2022.03.01 02:11:37]

WITH 구문 안에 불필요한 구문들이 너무 많네요.
- 사용자함수, Distinct, Group By, dense_rank, Order By, 등등
- 컬럼명이나 알리아스가 예약어인 rank 라는 것도 마음에 들지 않구요.
이 쿼리가 맞는 쿼리인지도 의문입니다.
- atype, btype 이 혼용되고 있는데? mtype, stype 이 아닌가 싶고.
- :pToDate 와 :toDate 가 사용되는데? 다른 값인지? 같은 값인지?
- Distinct 는 왜 하는건지?
의문 가는 부분은 너무 많은데
테이블 정보와 관계 등을 알 수가 없어 섣부르게 접근하기가 망설여지네요.
지금 이 상태로는 쿼리를 제가 고쳐드릴 수가 없습니다.
일단은 불필요한 요소들부터 제거해 보세요.
- 사용자함수, Distinct, Group By, dense_rank, Order By, 등등


by 기봉이 [2022.03.02 10:30:21]

네 감사합니다~! 말씀하신대로 불필요한 부분을 제거하고 재실행해봐야겠습니다. 정말 감사합니다


by 마농 [2022.03.02 13:25:05]

제 생각에는
현재 쿼리에서 불필요한 부분들을 제거해 나가기 보다는
필요한 부분만을 가지고 처음부터 새로 작성하는 것을 추천합니다.

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