안녕하세요 선배님들!
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 조인을 걸어도 성능은 마찬가지입니다..
해당 쿼리를 어떻게 하면 개선할 수 있을까요?
선배님들의 소중한 피드백 미리 감사드립니다 :)
REC_KEY 는 유일키 인가요?
ACCESSION_LOC 어느테이블 컬럼이며 INDEX 가 있나요?
혹시 ACCESSION_LOC 컬럼의 '11', '21' 값이 대다수는 아닌가요?
감사드립니다 아찌님 ^^
인덱스 걸고 테스트 해보도록 하겠습니다 :)
안녕하세요!
1. REC_KEY는 키가 맞습니다.
2. ACCESSION_LOC는 USER_TBL 테이블의 컬럼이고 인덱스는 걸려있지 않습니다.
3. ACCESSION_LOC 컬럼의 밸류가 11, 21인 레코드는 84만개 정도 있습니다.
답변 감사드립니다 ^^
1. USER_KEY 도 유일키인가요?
2. ACCESSION_LOC 컬럼에 인덱스가 있어야할것 같습니다.
3.NEO_MIS_INTEREST_REG_TBL 의 컬럼 USER_KEY 가 유일키이고
USER_TBL / CO_OLD_USER_TBL 의 컬럼 ACCESS_LOC 가 인덱스가 있어야 속도 개선이 될것같습니다.
답변 감사드립니다 아찌님!
인덱스가 아닌 쿼리 자체로는 개선이 힘들까요?
질문만 가지고 판단하기 힘들긴한데.
획기적으로 성능개선 하려면 INDEX가 필요할듯합니다.
그런데 운영중인 DB이시라면 INDEX 추가가 다른곳에 영향을 끼치는지 확인이 필요합니다.
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
;
선생님, 오늘도 감사드립니다 :)
아찌님이 말씀처럼 인덱스 걸어서 테스트 해보고,
선생님이 작성해주신 쿼리 이용해서도 테스트 해보도록 하겠습니다!
결과 공유 부탁드려요.
우주민님 user 테이블이 두개에요. 이름이 달라요
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 를 사용한 쿼리는 속도에 불리한 작용을 할까요?
으헛... 꼼꼼하게 확인 못했네요!! ㅠㅠ
3번이 응답이 가장 늦게 내려왔고, 1번 2번은 속도가 거의 동일합니다!
확인해보니, 마이그레이션한 데이터베이스에서 REC_KEY에 인덱스가 걸려있지 않아 발생했던 문제더라구요 ^^..
피드백 감사드립니다 선생님!