인덱스를 이용할 때 어떤 과정을 거치고, 어떻게 활용하는게 좋을지 알아보자
읽고자 하는 블록이 메모리(DB버퍼 캐시)에 없으면, 메모리의 어디에 위치시킬지 빈 공간(프리 버퍼)
를 찾아 해당 공간에 디스크에서 찾은 블록을 적재
클러스터링 팩터(데이터가 모여 있는 정도)
가 좋은 경우 버퍼 피닝 효과 발생
클러스터링 팩터
값이 블록 수
에 가까우면 좋은 것
클러스터링 팩터
값이 로우 수
에 가까우면 나쁜 것
인덱스를 통해 다음 행의 블록 번호
가 바뀔 때 1씩 증가
-- 클러스터링 팩터
블록
을 읽어 데이터를 추출하고 테이블 방문
후에 결과 건수
가 크게 변하지 않았다면 비효율 X테이블 방문 후 크게 줄었
다면 비효율 O블록
을 읽어, 적은 양의 데이터 추출
한 경우 비효율 Oex) 상품구분코드+상품명 인덱스가 존재할 때
select *
from 상품
where 상품구분코드='100101'
and 판매여부='Y';
기존 인덱스 사용 시, 테이블 액세스를 최종 결과 집합에 해당되는 만큼 액세스
-> (변경) 상품구분코드+상품명+판매여부 인덱스
테이블 랜덤 액세스를 한 번만 함
-- 주문일자+주문시간 인덱스
select /*+ gather_plan_statistics */ count(upper_case)
from ord
where ord_dt between '20120101' and '20120228'
and shop_no='SH0001';
인덱스에 매장번호
가 없기 때문에, 테이블에 방문하여 필터로 처리하였다.
125만건의 테이블을 방문하여, 6289건이 최종 결과 집합이 된다.
위 경우 약 124만건이 의미 없는 테이블 방문이므로, 인덱스에 shop_no
컬럼을 추가하는 것을 고려
기존 PK 컬럼
들을 선두
에 놓아야 함-- PK 인덱스 변경
alter table 테이블명 add constraint PK명 PRIMARY KEY(PK컬럼들) USING INDEX 인덱스명;
--ITEM_PK 인덱스가 item_id만 존재
select oi.ord_no, oi.item_id, i.item_nm, oi.ord_item_qty
from ord_item oi, item i
where ord_dt between '20120101' and '20120110'
and i.item_id=oi.item_id;
-- -->테이블 액세스 존재
--ITEM_PK 인덱스가 item_id+item_nm으로 구성
select oi.ord_no, oi.item_id, i.item_nm, oi.ord_item_qty
from ord_item oi, item i
where ord_dt between '20120101' and '20120110'
and i.item_id=oi.item_id;
--select의 i.item_nm을 위해 테이블에 방문하는 상황 발생X (테이블 액세스 발생X)
SQL문
에서 사용하는 모든 컬럼
을 인덱스에 포함select ord_dt, item_id, sum(ord_item_qty)
from ord_item
where ord_dt between '20120101' and '20120131'
group by ord_dt, item_id;
-- 인덱스 ord_dt+ord_hms일 땐 테이블 액세스 존재
-- 인덱스 ord_dt+ord_hms+item_id+ord_item_qty 일 경우 테이블 액세스 X
인덱스를 너무 많이 스캔하고, 스캔한 결과에서 일부
만 결과 집합이 된다면 인덱스 범위 스캔
이 잘못되었는지 체크 해야 함
등치(=)조건
과 범위 조건
이 섞인 상태에서 첫 번째 범위까지는 원하는 인덱스 스캔을 하지만, 범위 조건 뒤
부터는 원하지 않는 구간까지 스캔
where A=:a
and B=:b
and C between :c1 and :c2
and D=:d
-- A, B, C 컬럼은 원하는 구간을 찾아가지만 D는 A,B,C 만족하는 모든 인덱스를 스캔하고
-- 마지막에 결과 집합에 해당되는지만 체크하는 필터 값으로 사용됨
인덱스
는 주로 등치 조건
이 먼저 나오도록 구성해주는 것이 이득등치(=) 조건
으로 사용되고 자주 사용
되는 컬럼을 앞
등치(=) 조건
으로 사용되고 값의 수
가 적은
컬럼을 앞
자주 사용
되는 컬럼
선정테이블 랜덤 액세스
줄이기정렬
대신