B*Tree 인덱스를 정상적으로 사용하려면 범위 스캔 시작지점을 찾기 위해 루트 블록부터 리프블록까지의 수직적 탐색 과정을 거쳐야 한다.
인덱스 컬럼을 가공하면 정상적인 Index Range Scan이 불가능하다.
가장 흔한 가공 사례와 튜닝 방법
(1) 인덱스 사용이 불가능하거나 범위 스캔이 불가능한 경우 ( 사용하지 말자 )
- 아래 3가지 케이스는 그냥 외워 버리는게 좋을듯
case |
조건 |
예제 |
1 |
인덱스 컬럼을 조건절에서 좌변 가공하는 경우 |
select * from 업체 where substr(업체명, 1, 2) = '대한'; |
2 |
부정형 비교 |
select * from 고객 where 직업 <> '학생'; |
3 |
is not null 조건 |
select * from 사원 where 부서코드 is not null; |
(2) 인덱스 컬럼의 가공
인덱스 컬럼 가공 사례 |
튜닝 방안 |
select * from 업체 where substr(업체명, 1, 2) = '대한'; |
select * from 업체 where 업체명 like '대한%'; |
select * from 사원 where 월급여 * 12 = 36000000; |
select * from 사원 where 월급여 = 36000000 / 12; |
select * from 주문 where to_char(일시, 'yyyymmdd') = :dt; |
select * from 주문 where 일시 >= to_date(:dt, 'yyyymmdd') and 일시 <to_date(:dt, 'yyyymmdd') + 1; |
select * from 고객 where 연령 || 직업 = '30공무원'; |
select * from 고객 where 연령 = 30 and 직업 = '공무원'; |
select * from 회원사지점 where 회원번호 || 지점번호 = :str; |
select * from 회원사지점 where 회원번호 = substr(:str, 1, 2) and 지점번호 = substr(:str, 3, 4); |
select * from 주문 where nvl(주문수량, 0) >= 100; * nvl 때문에 index를 활용하지 않음 |
select * from 주문 where 주문수량 >= 100; |
select * from 주문 where nvl(주문수량, 0) <100;
|
* 주문수량이 NOT NULL이 아니면 수정 함수기반 인덱스(FBI) 생성 고려 => create index 주문_x01 on 주문(nvl(주문수량, 0) ); |
댓글