by 구루비 RANDOM ACCESS 랜덤액세스 INDEX SKIP SCAN ROWID ACCES PREDICATE FILTER PREDICATE [2017.03.22]
선두컬럼: 인덱스 구성상 앞쪽에 있는 컬럼
선행컬럼: 상대적으로 앞쪽에 있는 컬럼
ex
create table test (col1 number(4), col2 varchar2(10), col3 varchar2(10));
create index idx1 on test (col1, col2);
create index idx2 on test (col2, col1);
이와같은 테이블과 인덱스를 생성했을 때 idx 1 에서의 선두컬럼은 col1 이며 idx 선두컬럼은 col2
select 해당층,평당가, 입력일, 해당동, 매물구분,I연사용일수, 중개업소코드
from 매물아파트매매
where 아파트시세코드=' A01011350900056 '
and 평형 = '59'
and 평형타입 = 'A'
and 인터넷매물 between '1 ' ard '2 '
order by 입력일 desc
인텍스 선행 컬럼이 모두 '=' 조건일 때 필요한 범위만 스캔하고 멈출 수 있는 것은, 조건을 만
족하는 레코드가 모두 한데 모여 있기 때문이다.
인덱스 구성을 인터넷매물 + 아파트시세코드 + 평형 + 평형타입 순으로 바꾸고 나서 같
은 SQL을수행해보면,그림 1-39처럼 인덱스스캔 범위가넓어진다.
선두 컬럼이 적게 잡힐수 있는 인덱스 구조를 채택하는것이 중요.
select 해당층, 평당가, 입력일, 해당동, 매물구분, 연사용일수, 중개업소코드
frαn 매물아파트매매
where 인터넷매물 in('l', '2')
and 아파트시세코드= 'A01011350900056'
and 평형 = '59'
and 평형타입 = 'A'
order by 입력일 desc
select 해당층, 평당가, 입력일, 해당동, 매물구분, 연사용일수, 중개업소코드
frαn 매물아파트매매
where 인터넷매물 in('l')
and 아파트시세코드= 'A01011350900056'
and 평형 = '59'
and 평형타입 = 'A'
order by 입력일 desc
union all
select 해당층, 평당가, 입력일, 해당동, 매물구분, 연사용일수, 중개업소코드
frαn 매물아파트매매
where 인터넷매물 in('2')
and 아파트시세코드= 'A01011350900056'
and 평형 = '59'
and 평형타입 = 'A'
order by 입력일 desc
in-list 로 변경시 주의 사항
in-list는 union all 을 사용하여 해당 테이블을 한번 더 읽는 방법이므로 list 의 개수가 큰 경우에는 적합하지 않다.만약 해당 테이블에 인덱스를 추가하는데 문제가 없는 상황이라면 인덱스 추가후 힌트로 인덱스를 유도해주는 편이 좋으리라 생각된다.
create table t74
as
select rownurn 고객번호
, '2008' || lpad(ceil(rownurn/100000), 2, '0') 판매월
, deode(mod(rownurn,12),1,'A', 'B') 판매구분
, round(dbms_random.value(1000, 100000) , - 2) 판매금액
from dual
connect by level <= 1200000
select count(*)
from t74 t
where 판매구분 = 'A'
and 판매월 between '200801 ' and '200812 '
create index t74_IDX1 on t74 (판매구분, 판매월);
create index t74_IDX2 on t74 (판매월,판매구분);
인덱스 스킵스캔 사용 시
/*+ index_ss(t74 t74_IDX2)*/
'070' , '0' ,'보급' 조건으로 검색
SELECT 고객ID, 상품명, 지역, ...
FROM 가입상품
WHERE 회사 :com
AND 지역 :reg || ' % '
AND 상품명 LIKE :prod || ' % '
SELECT 고객ID, 상품명, 지역, ...
FROM 가입상품
WHERE 회사 :com
AND 지역 LIKE :reg || ' % '
AND 상품명 LIKE :prod || ' % '
select *
from (
select rownum rnum, 도서번호, 도서명, 가격, 저자, 출판사, isbn
frαn (
select 도서변호, 도서명 , 가격, 저자, 출판사, isbn
from 도서
where 도서명 like :book nm || '%'
order by 도서명
where rownum <= 100
where rnum >= 91
앞쪽 페이지는 원활하게 보이는 편이나 마지막 페이지 쪽 근처로 검색하면 느려진다.
– or-Expansion 을 이용하는 방법과 주의 사항
or 조건에 대한 expansion(union all 분기) 이 일어나면 뒤쪽 조건절이 먼저 실행
(9i기준 10g 의 경우 ordered_predicates 힌트 명시)
– rowid 를 concatenation 하면 결과에 오류 발생
rowid 와 암시적 형변환으로 변경된 rowidtochar(rowid) 는 정렬순서가 다르다.
select greatest( 'AAAH+WAAJAAHxTAA9', 'AAAH+WAAJAAAHxTAA+' ) from dual;
select greatest( chartorowid('AAAH+WAAJAAAHxTAA9'), chartorowid('AAAH+WAAJAAAHxTAA+')) from dual;
-- 인덱스를 스캔하면서 rowid를 필터링할 때 발생하는 비효율
rowid = 조건은 빠르지만 rowid >등의 범위 조건이면 효율적이지 않다.
between 대신 like 를 사용하는 이유는 단순하고 쉽기 때문
그러나 between 을 사용하면 like 를 사용하는 경우에 비해서 손해를 볼 일은 없다.
선분이력시 pk 를 포함하지 않으면 중복값이 발생하여 효율 저하
select /*+ index_desc(a idx_xOl) */ *
from 고객별연제금액 a
where 고객번호 = '123'
and '최근날짜' between 시작일 and 종료일
and rownum <= 1
select /*+ index_desc(a idx_xOl) */ *
from 고객별연제금액 a
where 고객번호 = '123'
and '과거날짜' between 시작일 and 종료일
and rownum <= 1
select *
from 고객별연체금액 a
where 고객번호 = '123'
and '최근날짜' between 시작일 and 종료일
and rownum <= 1
인댁스 구성이 [고책번호 + 시작일 + 종료일] 일 때
select /*+ index_desc (a idx_x01) */ *
from 고객별연체금액 a
where 고객번호 = '123'
and '20031010' between 시작일 and 종료일
and rownum <= 1
-인덱스를 경유하지 않고 테이블 전체를 스캨ㄴ할 때
4. 테이블 단계에서의 Filter Predicate (jd=3 filter 부분)
읽을거리: 인덱스 리빌드를 둘러싼 논쟁 http://ukja.tistory.com/82
요약: delete 작업후 인덱스는 다음 insert 시 정리및 재사용된다.
SQL> alter index t_idx shrink space compact ;
SQL> alter index t_idx rebuild online;
h5.index rebuild 실행하는 경우
131~179
- 강좌 URL : http://www.gurubee.net/lecture/3335
- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.