속도 개선이 필요합니다. ㅠ 0 4 1,464

by 널라리 [SQL Query] [2021.03.24 10:54:09]


하기 쿼리를 작성하였는데 속도가 안나네요. 

어떻게 하면 좀 더 속도를 낼수 있을까요?

 

SELECT       COL_1 --지차체명
           ,COL_2 --배출량
           ,COL_3 --처리량
           ,DECODE(AA2.COL_4, 0, 0, ROUND(((AA1.COL_2+AA1.COL_3)/AA2.COL_4) * 100,0)) COL4 --비율
        FROM (
                SELECT  '1' DIV 
                            ,COL_1
                            , SUM(COL_2) COL_2
                            ,SUM(COL_3) COL_3
                FROM
                       (
                        SELECT  
                                   GRC_INFO.CMPTNC_NM COL_1--관할관청    
                                   ,ROUND(SUM(DECODE( GIVE_QUN_NIT, '01', GIV_UNT, '02', GIV_UNT/1000,  GIV_UNT/1000000)),0) COL_2
                                   ,0 COL_3
                        FROM 
                            (SELECT *
                             FROM (
                                SELECT AB.*
                                FROM
                                    MAN1000 AB
                                WHERE AB.GIVE_DATE BETWEEN TO_TIMESTAMP('20200101', 'YYYYMMDD') AND TO_TIMESTAMP('20201231', 'YYYYMMDD')
                                ) AAB
                            ) A1
                         JOIN BAS1000 BAS1000
                        ON BAS1000.ENTN = a1.EMI_CHRG
                        JOIN T_ST_CMPTNC_STDR_INFO GRC_INFO
                        ON (GRC_INFO.CERFIN_GRC_CD = NVL(BAS1000.CITY_AUTH, BAS1000.CMPT_AUTH))
                        AND   GRC_INFO.CMPTNC_CD = '900' --'062'
                     WHERE 1 = 1
                            GROUP BY GRC_INFO.CMPTNC_GRC_GROUP_NM
                         UNION ALL
                        SELECT  
                                   GRC_INFO.CMPTNC_NM COL_1
                                   ,0 COL_2
                                   ,ROUND(SUM(DECODE( GIVE_QUN_NIT, '01', GIV_UNT, '02', GIV_UNT/1000,  GIV_UNT/1000000)),0) COL_3
                        FROM 
                            (SELECT *
                            FROM (
                                SELECT AB.*
                                FROM
                                    MAN1000 AB
                                WHERE AB.GIVE_DATE BETWEEN TO_TIMESTAMP('20200101', 'YYYYMMDD') AND TO_TIMESTAMP('20201231', 'YYYYMMDD')
                                ) AAB
                            ) A0
                         JOIN    man2000 a1
                         ON A0.MAN_NUMS = A1.MAN_NUMS    
                         JOIN BAS1000 BAS1000
                        ON BAS1000.ENTN = a1.TRT_CHRG
                         JOIN T_ST_CMPTNC_STDR_INFO GRC_INFO
                            ON (GRC_INFO.CERFIN_ISSU_CD = NVL(BAS1000.CITY_AUTH, BAS1000.CMPT_AUTH))
                        AND   GRC_INFO.CMPTNC_CD = '900' --'062'
                        WHERE 1 = 1
                            GROUP BY GRC_INFO.CMPTNC_NM
                  ) AAA1
                  GROUP BY COL_1
            ) AA1
        LEFT JOIN    (
                SELECT  '1' DIV 
                            ,SUM(COL_2) + SUM(COL_3) COL_4
                FROM
                       (
                        SELECT  
                                   GRC_INFO.CMPTNC_NM COL_1--관할관청    
                                   ,ROUND(SUM(DECODE( GIVE_QUNT_UNIT, '01', GIVE_QUNT, '02', GIVE_QUNT/1000,  GIVE_QUNT/1000000)),0) COL_2
                                   ,0 COL_3
                        FROM (SELECT *
                             FROM (
                                SELECT AB.*
                                FROM
                                    MAN1000 AB
                                WHERE AB.GIVE_DATE BETWEEN TO_TIMESTAMP('20200101', 'YYYYMMDD') AND TO_TIMESTAMP('20201231', 'YYYYMMDD')
                                ) AAB
                            ) A1
                         JOIN BAS1000 BAS1000
                        ON BAS100.ENTN = a1.EMI_CHRG
                         JOIN T_ST_CMPTNC_STDR_INFO GRC_INFO
                            ON (GRC_INFO.CERFIN_ISSU_CD = NVL(BAS1000.CITY_AUTH, BAS1000.CMPT_AUTH))
                        AND   GRC_INFO.CMPTNC_CD = '900' --'062'
                        WHERE
                            1 = 1
                            GROUP BY GRC_INFO.CMPTNC_NM
                         UNION ALL
                        SELECT  
                                   GRC_INFO.CMPTNC_NM COL_1
                                   ,0 COL_2
                                   ,ROUND(SUM(DECODE( RECV_QUNT_UNIT, '01',RECV_QUNT, '02', RECV_QUNT/1000, RECV_QUNT/1000000)),0) COL_3
                        FROM 
                            (SELECT * 
                             FROM man2000
                            WHERE RECV_DATE BETWEEN TO_TIMESTAMP('20200101', 'YYYYMMDD') AND TO_TIMESTAMP('20201231', 'YYYYMMDD')
                            ) a1
                         JOIN BAS1000 BAS1000
                        ON BAS1000.ENTN = a1.TRTM_CHRG
                         JOIN T_ST_CMPTNC_STDR_INFO GRC_INFO
                            ON (GRC_INFO.CERFIN_ISSU_CD = NVL(BAS1000.CITY_AUTH, BAS100.CMPT_AUTH))
                        AND   GRC_INFO.CMPTNC_CD = '900' --'062'
                        WHERE 1 = 1
                            GROUP BY GRC_INFO.CMPTNC_NM
                  ) AAAA2
            ) AA2
        ON AA1.DIV = AA2.DIV

by 마농 [2021.03.25 08:39:57]

1. 날짜 조건
- give_date, recv_date 의 data type 이 뭔가요?
- to_timestamp 를 사용하는게 맞나요?
- 해당 컬럼이 timestamp 형식이라면? 밀리초단위까지 저장되어 있지 않나요?
- 밀리초까지 저장되어 있다면? '20201231' 조건은 잘못된 조건입니다. 마지막 날짜 누락.
2. 쿼리가 일관성이 없는데?
- aa1 의 col3 에서는 man1000 의 give_date 조건주고 man2000 과 조인하고 give_qunt 을 이용하는데?
- aa2 의 col3 에서는 man2000 의 recv_date 조건주고 man1000 과 조인없이 recv_qunt 을 이용하네요?
- 서로 같은 조건으로 뽑아야 하는게 아닌지?
3. 불필요한 인라인뷰 사용
- aab, a0, a1 등의 인라인뷰 사용은 불필요합니다.


by 널라리 [2021.03.25 10:54:34]

1. 날짜 조건
- give_date, recv_date 의 data type 이 뭔가요? => date 타입입니다.
- to_timestamp 를 사용하는게 맞나요? => date타입이다보니 to_timestamp 함수를 썼습니다.
- 해당 컬럼이 timestamp 형식이라면? 밀리초단위까지 저장되어 있지 않나요? => 밀리초단위까지 저장되어 있습니다.
- 밀리초까지 저장되어 있다면? '20201231' 조건은 잘못된 조건입니다. 마지막 날짜 누락. => 아...
2. 쿼리가 일관성이 없는데?
- aa1 의 col3 에서는 man1000 의 give_date 조건주고 man2000 과 조인하고 give_qunt 을 이용하는데?
- aa2 의 col3 에서는 man2000 의 recv_date 조건주고 man1000 과 조인없이 recv_qunt 을 이용하네요? => 데이터정보를 가져오는 테이블이 조금 다르다보니 그 테이블의 날짜정보로 조건을 주었습니다.
- 서로 같은 조건으로 뽑아야 하는게 아닌지? => 이 말씀 참고하겠습니다.
3. 불필요한 인라인뷰 사용
- aab, a0, a1 등의 인라인뷰 사용은 불필요합니다. => 참고하겠습니다.


by 마농 [2021.03.25 11:20:19]

1. Date 컬럼이라면? Timestamp 가 아닌 Date 조건을 줘야죠
- AND give_date >= TO_DATE('20200101', 'yyyymmdd')
- AND give_date <  TO_DATE('20201231', 'yyyymmdd') + 1
2. 일관성이 없는 쿼리 부분
- 조건이 서로 다른 부분을 동일하게 조건을 맞춰 준다면?
- 쿼리를 개별 처리하여 조인할 필요가 없습니다.
- 분석함수를 통한 비율 계산이 가능해 집니다.
- RATIO_TO_REPORT http://gurubee.net/lecture/2675


by 널라리 [2021.03.25 13:17:19]

늘 좋은 의견과 정보 감사드립니다.^^

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