안녕하세요~
쿼리를 짜다가 너무 비효율적이여서 문의 드려요.
같은 테이블을 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')
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 ;
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가 어떤게 더 큰지 모른다는 가정하에 어거지로 한번 해봤습니다. ㅋㅋ