인덱스 설계가 어려운 이유

개발 단계에서 최적 인덱스 설계의 중요성

가장 중요한 두 가지 선택 기준

스캔 효율성 이외의 판단 기준

img
select /*+ leading(a) use_nl(b) */
       b.상품코드, b.상품명, a.고객번호, a.거래일자, a.거래량, a.거래금액
from   거래 a, 상품 b
where  a.거래구분코드 = 'AC'
and    a.거래일자 between '20090101' and '20090131'
and    b.상품번호 = a.상품번호
and    b.상품분류 = '가전'
select /*+ leading(b) use_nl(a) */
       b.상품코드, b.상품명, a.고객번호, a.거래일자, a.거래량, a.거래금액
from   거래 a, 상품 b
where  a.거래구분코드 = 'AC'
and    a.거래일자 between '20090101' and '20090131'
and    b.상품번호 = a.상품번호
and    b.상품분류 = '가전'

공식을 초월한 전략적 설계

소트 연산을 생략하기 위한 컬럼 추가

select 계약ID, 청약일자, 입력자ID, 계약상태코드, 보험시작일자, 보험종료일자
from   계약
where  취급지점ID = :trt_brch_id
and    청약일자 between :sbcp_dt1 and :sbcp_dt2
and    입력일자 >= trunc(sysdate - 3)
and    계약상태코드 in ( :ctr_stat_cd1, :ctr_stat_cd2, :ctr_stat_cd3 )
order by 청약일자, 입력자ID
img

IN조건은 '='이 아니다

select 고객번호, 고객명, 거주지역, 혈액형, 연령
from   고객
where  거주지역 = '서울'
and    혈액형 in ( 'A', 'O' )
order by 연령
거주지역 혈액형 연령
서울 A 23
서울 A 35
서울 A 48
서울 A 62
서울 O 29
서울 O 32
서울 O 45
서울 O 57
select 고객번호, 고객명, 거주지역, 혈액형, 연령
from   고객
where  거주지역 = '서울'
and    혈액형 = 'A'
union all
select 고객번호, 고객명, 거주지역, 혈액형, 연령
from   고객
where  거주지역 = '서울'
and    혈액형 = 'O'
order by 연령

결합 인덱스 선택도

select count(*) as NDV, max(cnt) as MX_CARD, min(cnt) MN_CARD, avg(cnt) as AVG_CARD
from (
    select 계약ID, 취급지점ID, count(*) as cnt
    from   계약조직
    where (계약ID is not null or 취급지점ID is not null)
    group by 계약ID, 취급지점ID
)

컬럼 순서 결정 시, 선택도 이슈

-- 둘 다 인덱스 엑세스 조건이므로 어떤 컬럼이 앞으로 오든 인덱스 스캔 범위는 같음
WHERE 성별 = :GENDER
AND 고객번호 = :CUST_NO
-- 조건1
WHERE 고객등급 = :V1
AND   고객번호 = :V2
AND   거래일자 >= :V3

-- 조건2
WHERE 고객등급 = :V1
AND   고객번호 = :V2
AND   거래일자 >= :V3
AND   거래유형 = :V4

-- 조건3
WHERE 고객등급 = :V1
AND   고객번호 = :V2
AND   거래일자 >= :V3
AND   상품번호 = :V5

-- 조건4
WHERE 고객등급 = :V1
AND   고객번호 = :V2
AND   거래일자 >= :V3
AND   거래유형 = :V4
AND   상품번호 = :V5
img

중복 인덱스 제거

실습1

컬럼명 NDV
거래일자 2,356
관리지점번호 127
일련번호 1,850
계좌번호 5,956
종목코드 1,715
결제일자 2,356
조건절 인덱스
계좌번호 = N1
계좌번호 =, 거래일자 = N1
계좌번호 =, 거래일자 BETWEEN N1
거래일자 = N3
거래일자 BETWEEN N3
조건절 인덱스
관리지점번호 =, 거래일자 = PK
관리지점번호 =, 거래일자 BETWEEN PK
거래일자 = N3
거래일자 BETWEEN N3

실습2

컬럼명 NDV
주소ID 736,000
건물동번호 175
건물호번호 3,052
관리번호 250,782
상태구분코드 3