해당 통계 쿼리를 개선할 방법.. 0 2 834

by matrixkdg [SQL Query] [2017.12.18 13:26:37]


기존 쿼리가 있었는데 속도도 너무 느리고 통계가 잘못나오고 있어서 제가 한 차례 수정하던차에 막혀서 질문올리게되었습니다.

결과는
01     21    x   1  21
02     46    x   1  47
03     72    x   1  73
04      0    x   1  1
합계   139   x   5  142
대강 요런식으로 나오는 쿼리인데

0건 처리 때문에 아우터 구조로 사용하기위해 디폴트 헤더 정보가 필요하여 유니온으로 위 테이블 구성후에 만들었습니다만..

저 헤더 구조때문에 없는 값일 경우 무조건 기준건이 한건이 나와버리는게 문제가 되고 있습니다.

01   21 x  1  21
02   46 x  1  47
03   72 x  1  73
04   0  0  0  1   -->  이런식..
합계 139 x 5 142


문제는 해당 0건 처리때문에 count(*)를 사용하지 못하는점 해서 아래 필드 (TOT)처럼 각각 해주지 않으면 안되는 상황인데.
이부분을 정리할수 있는 방법이 없을까요? 그때문에 인라인으로 한번더 감싸주는건 좀 아닌거같아서;; 너무 효율성 없어보이네요..

마지막으로 아래 조건 시 대상이 3984904 건이고 결과값을 가져오는데 8초정도 걸리네요..
더 빠르게 할 방법이 있을까요?


SELECT A.OPEN_TYPE
                ,SUM ( DECODE ( MSG_TYPE , 'IS' , 1 , 0 ) ) OPEN_MSG_IS
                    ,ROUND( SUM ( DECODE ( MSG_TYPE , 'IS' , 1 , 0 ) ) / COUNT(*) * 100 , 2 ) USER_OPEN_MSG_IS
                ,SUM ( DECODE ( MSG_TYPE , 'NS' , 1 , 0 ) ) OPEN_MSG_NS
                    ,ROUND( SUM ( DECODE ( MSG_TYPE , 'NS' , 1 , 0 ) ) / COUNT(*) * 100 , 2 ) USER_OPEN_MSG_NS                              
                 ,SUM ( DECODE ( MSG_TYPE , 'MS' , 1 , 0 ) ) OPEN_MSG_MS
                    ,ROUND( SUM ( DECODE ( MSG_TYPE , 'MS' , 1 , 0 ) ) / COUNT(*) * 100 , 2 ) USER_OPEN_MSG_MS             
                 ,SUM ( DECODE ( MSG_TYPE , 'FS' , 1 , 0 ) )  OPEN_MSG_FS
                    ,ROUND( SUM ( DECODE ( MSG_TYPE , 'FS' , 1 , 0 ) ) / COUNT(*) * 100 , 2 ) USER_OPEN_MSG_FS
                    , SUM ( DECODE ( MSG_TYPE , 'IS' , 1 , 0 ) )  + SUM ( DECODE ( MSG_TYPE , 'NS' , 1 , 0 ) ) + SUM ( DECODE ( MSG_TYPE , 'MS' , 1 , 0 ) ) + SUM ( DECODE ( MSG_TYPE , 'FS' , 1 , 0 ) ) TOT
                    --,COUNT(*)                                  
    FROM    
                (   
                    SELECT '01' OPEN_TYPE FROM    DUAL UNION
                    SELECT '02' OPEN_TYPE FROM    DUAL UNION
                    SELECT '03' OPEN_TYPE FROM    DUAL UNION
                    SELECT '04' OPEN_TYPE FROM    DUAL
                ) A
                ,(
                    SELECT OPEN_DT,OPEN_TYPE , MSG_TYPE 
                    FROM ICSM_SCANNER_OPEN_TB A
                              ,(  
                                SELECT CERT_NUM,TARGET_AREA_NM,SIDO_CD,GUGUN_CD,SHOP_NM FROM (
                                    SELECT DISTINCT CERT_NUM,TARGET_AREA_NM,SIDO_CD,GUGUN_CD,SHOP_NM
                                    FROM ICTMADMIN.VIEW_PRECON_REQ_BATCH
                                UNION ALL
                                    SELECT DISTINCT CERT_NUM,''TARGET_AREA_NM,''SIDO_CD,''GUGUN_CD,''SHOP_NM
                                    FROM ICTMADMIN.VIEW_PYRAMID_REQ B )
                                ) B  
                                WHERE  OPEN_DT >= '20170501000000'
                                AND        OPEN_DT <= '20171215235959'
                                AND         A.CERT_NUM = B.CERT_NUM
                ) B
    WHERE   A.OPEN_TYPE = B.OPEN_TYPE(+)
    GROUP BY ROLLUP(A.OPEN_TYPE)                     
    ORDER BY A.OPEN_TYPE

 

by 우리집아찌 [2017.12.18 15:46:49]

대충봐서 그런가 ?

OUTER JOIN 인데 왜 UNION ALL 하는지 잘 모르겠네요?

맨 마지막 SELECT 절에서 가공하면 되지않나요?

 


by 마농 [2017.12.19 10:03:29]

union all 을 일단 제거해 보세요.
distinct 가 왜 필요한지? 검토해 보세요.
view 내부 쿼리에 비효율은 없는지? 확인해 보세요.

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