중복 조회 튜닝 기초 쿼리질문입니다. 0 4 1,536

by poodle [Oracle Tuning] 기초쿼리 튜닝 [2017.02.27 16:31:55]


안녕하세요~

쿼리를 짜다가 너무 비효율적이여서 문의 드려요.

같은 테이블을 3번이나 조회를 하고 있어요

from , to 기관코드가 들어오면 이 코드값으로 

SORT순번을 찾고 이 순번에 맞는 기관코드를 조회해야 합니다.

아래와 같은 방법 외에 좋은 방법이 없을까요?????

                                                      
WITH untTb AS(
    select '1' unt, '서울본부' unt_nm,'Y' use_yn,1  srt_seq from dual  union all
    select '5' unt, '경기본부','Y',2 from dual  union all
    select '3' unt, '인천본부', 'Y' use_yn ,3 from dual union all
    select '2' unt, '부산본부','Y',4 from dual  union all
    select '4' unt, '대구본부','Y',5 from dual  
)      
select unt from untTb
where use_yn = 'Y'
and srt_seq >= (select srt_seq from untTb where unt='5')
and srt_seq <= (select srt_seq from untTb where unt='2')

 

 

by jkson [2017.02.27 17:24:03]

짱구를 굴려봐도 머리가 안 좋아서 그런지 잘 생각이 안나네요. 많이 줄여봐야 기본적으로 테이블 2번은 SELECT 해야할 것 같은데..

작성하신 쿼리도 UNT에 적당한 인덱스가 있고 SRT_SEQ에 적당한 인덱스가 있다면 UNIQUE SCAN후 바로 RANGE SCAN할 것이라

성능상 큰 문제는 없을 것 같습니다만..


by 마농 [2017.02.27 17:24:52]

1. 서브쿼리 안에도 use_yn = 'Y' 조건이 있어야 할 것 같은데요?
  - 조건 유무에 따라 의미가 전혀 다른 쿼리가 될 수도 있습니다.
2. 적절한 인덱스가 존재한다면?
  - 여러번 읽는 것이 꼭 나쁜 것만은 아닙니다.
  - unt 로 index unique scan 2번 하고
  - sort_seq 로 index range scan 범위 검색
3. 분석함수를 이용하면 1번 스캔으로 가능
  - 단, 테이블 전체 풀스캔 및 정렬 등을 해야함.
4. 어떤걸 선택할지?
  - 여러번 읽더라도 인덱스를 이용할지?
  - 한번만 읽지만 풀스캔에 정렬까지 해야 할지?
  - 테이블이 크지 않다면? 풀스캔 한번에 분석함수 사용이 좋을 듯 하고
  - 테이블이 크고 적절한 인덱스가 존재한다면? 인덱스를 이용하는 방법이 좋을 듯.
 

SELECT unt
  FROM (SELECT unt
             , srt_seq
             , MIN(DECODE(unt, '5', srt_seq)) OVER() s
             , MIN(DECODE(unt, '2', srt_seq)) OVER() e
          FROM untTb
        )
 WHERE srt_seq BETWEEN s AND e
;

 


by 랑에1 [2017.02.27 17:44:15]
WITH untTb AS(
    select '1' unt, '서울본부' unt_nm,'Y' use_yn,1  srt_seq from dual  union all
    select '5' unt, '경기본부','Y',2 from dual  union all
    select '3' unt, '인천본부', 'Y' use_yn ,3 from dual union all
    select '2' unt, '부산본부','Y',4 from dual  union all
    select '4' unt, '대구본부','Y',5 from dual  
)      

SELECT unt
FROM 
(
  SELECT a.*, SUM(sr1) OVER() srt1, SUM(sr2) OVER() srt2
  FROM 
  (
    select untTb.*, DECODE(:input1, unt, srt_seq) sr1, DECODE(:input2, unt, srt_seq) sr2 from untTb 
    where use_yn = 'Y'
  ) a
) a
WHERE srt_seq BETWEEN LEAST(srt1, srt2) AND GREATEST(srt1, srt2)

unt 값으로 srt_seq가 어떤게 더 큰지 모른다는 가정하에
어거지로 한번 해봤습니다. ㅋㅋ

 


by poodle [2017.02.27 18:15:14]

답변 모두 감사합니다~

데이터가 많지 않아서 마농님 말씀대로 2번으로 해야 할 것 같습니다.

같은 테이블을 여러번 읽는게 합리적이지 못하단 생각만 하고 막상 성능에 대해선 생각을 못하고 있었네요 ㅠ.ㅠ

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