ORACLE UNION 쿼리 성능 개선 관련 질문입니다. 1 14 5,266

by 도뎡이 [SQL Query] oracle union 쿼리성능개선 [2022.11.29 18:33:55]


안녕하세요 선배님들!

NEO_MIS_INTEREST_REG_TBL 테이블을 기준으로 USER_TBL과 CO_OLD_USER_TBL을 조인해서 전체 데이터를 UNION 하여 GROUP BY 하는 다음의 쿼리가 있습니다.

 

SELECT
    CD_INTEREST,
    count(*) CNT
FROM
    (
    SELECT
        N.CD_INTEREST
    FROM
        NEO_MIS_INTEREST_REG_TBL N,
        USER_TBL U
    WHERE
        N.USER_KEY = U.REC_KEY
        AND ACCESS_LOC IN ('11', '21')
UNION ALL
    SELECT
        N.CD_INTEREST
    FROM
        NEO_MIS_INTEREST_REG_TBL N,
        CO_OLD_USER_TBL U
    WHERE
        N.USER_KEY = U.REC_KEY
        AND ACCESSION_LOC IN ('11', '21')
        )
GROUP BY
    CD_INTEREST
;

 

기준이 되는 테이블은 NEO_MIS_INTEREST_REG_TBL 테이블이고, 조건절의 파라미터는 동일한데
해당 쿼리를 실행하면 응답이 내려오는 데까지 9~10초 정도가 소요됩니다.

해당 쿼리를 조인으로 변경해 보려 했으나, LEFT 조인을 걸어도 성능은 마찬가지입니다..

해당 쿼리를 어떻게 하면 개선할 수 있을까요?

선배님들의 소중한 피드백 미리 감사드립니다 :)

 

by 우리집아찌 [2022.11.29 21:27:31]

REC_KEY 는 유일키 인가요?

ACCESSION_LOC 어느테이블 컬럼이며 INDEX 가 있나요?

혹시 ACCESSION_LOC 컬럼의 '11', '21' 값이 대다수는 아닌가요?


by 도뎡이 [2022.11.30 10:56:33]

안녕하세요!

1. REC_KEY는 키가 맞습니다.

2. ACCESSION_LOC는 USER_TBL 테이블의 컬럼이고 인덱스는 걸려있지 않습니다.

3. ACCESSION_LOC 컬럼의 밸류가 11, 21인 레코드는 84만개 정도 있습니다.

답변 감사드립니다 ^^


by 우리집아찌 [2022.11.30 11:24:05]

1. USER_KEY 도 유일키인가요?

2. ACCESSION_LOC 컬럼에 인덱스가 있어야할것 같습니다.

3.NEO_MIS_INTEREST_REG_TBL 의 컬럼 USER_KEY  가 유일키이고

  USER_TBL / CO_OLD_USER_TBL 의 컬럼 ACCESS_LOC 가 인덱스가 있어야 속도 개선이 될것같습니다.

  

 


by 도뎡이 [2022.11.30 13:05:34]

답변 감사드립니다 아찌님!

인덱스가 아닌 쿼리 자체로는 개선이 힘들까요?


by 우리집아찌 [2022.11.30 15:56:41]

질문만 가지고 판단하기 힘들긴한데.

획기적으로 성능개선 하려면 INDEX가 필요할듯합니다.

그런데 운영중인 DB이시라면 INDEX 추가가 다른곳에 영향을 끼치는지 확인이 필요합니다.

 


by 도뎡이 [2022.11.30 16:36:05]

감사드립니다 아찌님 ^^

인덱스 걸고 테스트 해보도록 하겠습니다 :)


by 마농 [2022.11.30 13:09:32]
SELECT cd_interest
     , SUM(cnt) cnt
  FROM (SELECT n.cd_interest
             , COUNT(*) cnt
          FROM neo_mis_interest_reg_tbl n
             , user_tbl u
         WHERE n.user_key = u.rec_key
           AND u.access_loc IN ('11', '21')
         GROUP BY n.cd_interest
         UNION ALL
        SELECT n.cd_interest
             , COUNT(*) cnt
          FROM neo_mis_interest_reg_tbl n
             , co_old_user_tbl u
         WHERE n.user_key = u.rec_key
           AND u.accession_loc IN ('11', '21')
         GROUP BY n.cd_interest
        )
 GROUP BY cd_interest
;

SELECT n.cd_interest
     , COUNT(*) cnt
  FROM neo_mis_interest_reg_tbl n
     , (SELECT rec_key
          FROM user_tbl
         WHERE access_loc IN ('11', '21')
         UNION ALL
        SELECT rec_key
          FROM co_old_user_tbl
         WHERE accession_loc IN ('11', '21')
        ) u
 WHERE n.user_key = u.rec_key
 GROUP BY n.cd_interest
;

SELECT n.cd_interest
     , COUNT(a.rec_key)
     + COUNT(b.rec_key) cnt
  FROM neo_mis_interest_reg_tbl n
  LEFT OUTER JOIN user_tbl a
    ON n.user_key = a.rec_key
   AND a.access_loc IN ('11', '21')
  LEFT OUTER JOIN co_old_user_tbl b
    ON n.user_key = b.rec_key
   AND b.accession_loc IN ('11', '21')
 WHERE a.rec_key IS NOT NULL
    OR b.rec_key IS NOT NULL
 GROUP BY n.cd_interest
;

 


by 도뎡이 [2022.11.30 16:36:54]

선생님, 오늘도 감사드립니다 :)

아찌님이 말씀처럼 인덱스 걸어서 테스트 해보고,

선생님이 작성해주신 쿼리 이용해서도 테스트 해보도록 하겠습니다!


by 마농 [2022.11.30 17:01:21]

결과 공유 부탁드려요.


by 우주민 [2022.11.30 17:05:44]
SELECT 
    n.cd_interest
    ,COUNT(*) cnt
FROM neo_mis_interest_reg_tbl n
    , user_tbl u
WHERE n.user_key = u.rec_key
AND (u.access_loc IN ('11', '21') OR u.accession_loc IN ('11', '21'))
GROUP BY n.cd_interest

 

혹시 OR 를 사용한 쿼리는 속도에 불리한 작용을 할까요?


by 마농 [2022.11.30 17:13:01]

우주민님 user 테이블이 두개에요. 이름이 달라요


by 우주민 [2022.11.30 17:21:23]

으헛... 꼼꼼하게 확인 못했네요!! ㅠㅠ


by 도뎡이 [2022.12.01 10:24:05]

3번이 응답이 가장 늦게 내려왔고, 1번 2번은 속도가 거의 동일합니다!

확인해보니, 마이그레이션한 데이터베이스에서 REC_KEY에 인덱스가 걸려있지 않아 발생했던 문제더라구요 ^^..

피드백 감사드립니다 선생님!

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