쿼리 튜닝 부탁드려여 ㅠ 0 5 1,362

by 뜨디 [SQL Query] [2021.01.29 00:46:50]


20210129_004554.png (82,810Bytes)

기존쿼리에서 WITH내부 쿼리는 튜닝을 했는데

추가로 SQL WINDOW SORT 부하 줄일수있게 쿼리 수정이 가능할까여?

 ㅠㅠ

 

1. 쿼리

 

 WITH /* 쿼리수정한거2 */
  DUP_LST_INF AS (SELECT 
/*+ USE_HASH(B,A) DRIVING(B) INDEX(A,PK_WANL_A_DW_ACTION_TR_D) INDEX(B,PK_WANL_A_DW_ACTION_PARAM_TR_D) */
          A.DW_DATE ,
               A.CHANNEL_CD ,
               A.SESSION_ID ,
               A.PAGE_SEQ ,
               A.PAGE_ID ,
               SUBSTR(B.PARAM_VAL, -4) AS T_EVT_CD ,
               LTRIM(SUBSTR(B.PARAM_VAL, 1, 3), 0) AS T_PAGE_CD ,
                       CASE
                         WHEN SUBSTR(B.PARAM_VAL, -4) = 'E040'
           AND NVL(B.PARAM_VAL, '-') IN ('301',
                       '501') THEN '1'
                         ELSE '2'
                       END AS CHK_RN -- 홈버튼 클릭 시, 홈탭이 최우선
               ,
               A.URL_ID ,
               A.ACTION_TYPE_CD ,
               A.ACCESS_TIME ,
               B.PARAM_VAL AS ETAG1 ,
               NVL(B.PARAM_VAL, '-') AS MENUID -- 메뉴아이디없을경우..임시(RN 사용)
          FROM EBIZDW.WANL_A_DW_ACTION_TR_D A LEFT JOIN EBIZDW.WANL_A_DW_ACTION_PARAM_TR_D B ON A.DW_DATE = B.DW_DATE
           AND A.CHANNEL_CD = B.CHANNEL_CD
           AND A.SESSION_ID = B.SESSION_ID
           AND A.PAGE_SEQ = B.PAGE_SEQ
           AND A.PAGE_ID = B.PAGE_ID
           AND B.PARAM_NM ='ETAG1'
           AND A.DW_DATE = B.DW_DATE
           AND B.PARAM_NM ='MENUID'
           AND B.PAGE_ID='2'
         WHERE A.DW_DATE = '20210101'
           AND A.CHANNEL_CD ='A' --모바일
         UNION ALL
SELECT 
/*+ USE_HASH(B,A) DRIVING(B) INDEX(A,PK_WANL_A_DW_ACTION_TR_D) INDEX(B,PK_WANL_A_DW_ACTION_PARAM_TR_D) */
          A.DW_DATE ,
               A.CHANNEL_CD ,
               A.SESSION_ID ,
               A.PAGE_SEQ ,
               A.PAGE_ID ,
               SUBSTR(B.PARAM_VAL, -4) AS T_EVT_CD ,
               LTRIM(SUBSTR(B.PARAM_VAL, 1, 3), 0) AS T_PAGE_CD ,
                       CASE
                         WHEN SUBSTR(B.PARAM_VAL, -4) = 'E040'
           AND NVL(B.PARAM_VAL, '-') IN ('301',
                       '501') THEN '1'
                         ELSE '2'
                       END AS CHK_RN -- 홈버튼 클릭 시, 홈탭이 최우선
               ,
               A.URL_ID ,
               A.ACTION_TYPE_CD ,
               A.ACCESS_TIME ,
               B.PARAM_VAL AS ETAG1 ,
               NVL(B.PARAM_VAL, '-') AS MENUID -- 메뉴아이디없을경우..임시(RN 사용)
          FROM EBIZDW.WANL_A_DW_ACTION_TR_D A LEFT JOIN EBIZDW.WANL_A_DW_ACTION_PARAM_TR_D B ON A.DW_DATE = B.DW_DATE
           AND A.CHANNEL_CD = B.CHANNEL_CD
           AND A.SESSION_ID = B.SESSION_ID
           AND A.PAGE_SEQ = B.PAGE_SEQ
           AND A.PAGE_ID = B.PAGE_ID
           AND B.PARAM_NM ='ETAG1'
           AND A.DW_DATE = B.DW_DATE
           AND B.PARAM_NM ='MENUID'
           AND B.PAGE_ID='2'
         WHERE A.DW_DATE = '20210101'
           AND A.CHANNEL_CD ='M' --앱웹
         UNION ALL
SELECT 
/*+ USE_HASH(B,A) DRIVING(B) INDEX(A,PK_WANL_A_DW_ACTION_TR_D) INDEX(B,PK_WANL_A_DW_ACTION_PARAM_TR_D) */
          A.DW_DATE ,
               A.CHANNEL_CD ,
               A.SESSION_ID ,
               A.PAGE_SEQ ,
               A.PAGE_ID ,
               SUBSTR(B.PARAM_VAL, -4) AS T_EVT_CD ,
               LTRIM(SUBSTR(B.PARAM_VAL, 1, 3), 0) AS T_PAGE_CD ,
                       CASE
                         WHEN SUBSTR(B.PARAM_VAL, -4) = 'E040'
           AND NVL(B.PARAM_VAL, '-') IN ('301',
                       '501') THEN '1'
                         ELSE '2'
                       END AS CHK_RN -- 홈버튼 클릭 시, 홈탭이 최우선
               ,
               A.URL_ID ,
               A.ACTION_TYPE_CD ,
               A.ACCESS_TIME ,
               B.PARAM_VAL AS ETAG1 ,
               NVL(B.PARAM_VAL, '-') AS MENUID -- 메뉴아이디없을경우..임시(RN 사용)
          FROM EBIZDW.WANL_A_DW_ACTION_TR_D A LEFT JOIN EBIZDW.WANL_A_DW_ACTION_PARAM_TR_D B ON A.DW_DATE = B.DW_DATE
           AND A.CHANNEL_CD = B.CHANNEL_CD
           AND A.SESSION_ID = B.SESSION_ID
           AND A.PAGE_SEQ = B.PAGE_SEQ
           AND A.PAGE_ID = B.PAGE_ID
           AND B.PARAM_NM ='ETAG1'
           AND A.DW_DATE = B.DW_DATE
           AND B.PARAM_NM ='MENUID'
           AND B.PAGE_ID='2'
         WHERE A.DW_DATE = '20210101'
           AND A.CHANNEL_CD ='P' --PC
               )
SELECT DW_DATE AS STD_DD ,
       SUBSTR(DW_DATE, 1, 6) AS STD_YM ,
       CHANNEL_CD AS CHNL_DTL_CD ,
       SESSION_ID AS SESON_ID ,
       PAGE_SEQ AS PV_SRES_NO ,
       PAGE_ID AS WPGE_ID ,
       ACTION_TYPE_CD AS CUST_BHVR_TYPE_CD ,
       SYSDATE AS LOAD_DT
  FROM (SELECT DW_DATE ,
               CHANNEL_CD ,
               SESSION_ID ,
               PAGE_SEQ ,
               PAGE_ID ,
               ACTION_TYPE_CD ,
               ACCESS_TIME ,
               ETAG1 ,
               MENUID ,
               ROW_NUMBER() OVER(PARTITION BY DW_DATE, CHANNEL_CD, SESSION_ID, PAGE_ID, ACTION_TYPE_CD, ACCESS_TIME
                 ORDER BY ACCESS_TIME, MENUID) AS RN
          FROM (SELECT DW_DATE ,
                       CHANNEL_CD ,
                       SESSION_ID ,
                       PAGE_SEQ ,
                                       CASE
                                         WHEN PAGE_ID ='104'
                   AND T_EVT_CD IN ('E003',
                               'E115') THEN LEAD(T_PAGE_CD) OVER(PARTITION BY DW_DATE, CHANNEL_CD, SESSION_ID
                         ORDER BY PAGE_SEQ)
                                         ELSE PAGE_ID
                                       END AS PAGE_ID ,
                                       CASE
                                         WHEN PAGE_ID ='104'
                   AND T_EVT_CD IN ('E003',
                               'E115') THEN 'PV'
                                         ELSE ACTION_TYPE_CD
                                       END AS ACTION_TYPE_CD ,
                       ACCESS_TIME ,
                       ETAG1 ,
                       NVL(MENUID, '-') AS MENUID -- 메뉴아이디없을경우..임시(RN 사용)
                  FROM DUP_LST_INF ) )
 WHERE RN >1
   AND 1=1 ;
 

 

 

2. XPLAN

첨부파일 확인 부탁드립니다.

 

 

by 마농 [2021.01.29 11:21:06]

-- 쿼리가 모순이 있네요. --
1. CASE WHEN SUBSTR(b.param_val, -4) = 'E040' AND NVL(b.param_val, '-') IN ('301', '501') THEN '1' ELSE '2' END
- AND 로 연결된 2개 조건이 서로 상충되는 조건으로 2개 조건을 동시 만족할 수 없으므로 해당 Case 조건은 항상 거짓
2. CASE WHEN page_id = '104' AND t_evt_cd IN ('E003', 'E115')
- WITH 안에서 page_id = 2 인것만 가져오므로 page_id = '104' 조건을 만족할 수 없으므로 해당 Case 조건은 항상 거짓
즉 두가지 case 구문은 항상 거짓이므로 case 구문 자첵 불필요해 보입니다.
3. RN > 1 조건은 어떤 의도로 사용된 걸까요?
- 보통은 작다 조건을 많이 사용하는데 크다 조건은 흔치 않은 조건이네요?

-- 쿼리 튜닝 --
With 문 안에서 UNION 3번 한 것은 IN 조건으로 바꾸면 One 쿼리로 가능합니다.
- AND a.channel_cd IN ('A', 'M', 'P')


by 뜨디 [2021.01.29 14:02:06]

쿼리튜닝 - 대답 감사합니다. 한번 확인해 보겠습니다! union all 로 푸는게 더 성능이 좋더라구여 in보다 지금 성능의 제일 문제가 되는부분이 윈도우 함수로인한 윈도우 sort에서 시간을 거의 잡아먹는데 저 윈도우 펑션 2번쓰는걸 쿼리를 수정하여 1번의 사용으로 변경이 가능할까 해서여


by 뜨디 [2021.01.29 14:02:42]

2번 : 저도 그부분이 의아하여 개발자분게 무슨 의도가있는건지 확인 해야합니다.


by 뜨디 [2021.01.29 14:03:19]

1,2번도 개발자에게 확인 예정입니다.


by 마농 [2021.01.29 14:09:06]

UNION 이 더 빠르다면?
RN 을 만드는 것도 UNION 각각의 쿼리에서 사용하세요.

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