- 4.1 인덱스의 선정 기준
- 4.1.1. 테이블 형태별 적용기준
- 4.1.2. 분포도와 손익 분기점
- 4.1.3. 인덱스 머지와 결합 인덱스 비교
- 4.1.4. 결합 인덱스의 특징
- 4.1.5. 결합 인덱스의 컬럼 순서 결정 기준
- 4.1.6. 인덱스 선정 절차
4.1 인덱스의 선정 기준
- 인덱스가 선정되면 득이 되는 경우와 반대인 경우가 있다.
- 역활이 중복될 경우 안 좋은 영향이 발생할 수 있다.
- 모든 엑세스 형태와 분석을 토대로 이상적인 컬럼 구성과 순서 결정을 통해 단위 인덱스의 역량을 강화시키고, 최소의 인덱스로 모든 엑세스 형태를 만족할 수 있도록 해야한다.
- 가능한 실측자료(엑세스 형태 수집, 분석, 엑세스의 빈도, 처리범위의 크기, 분포도, 테이블의 크기, 엑세스 유형등)를 활용하여 종합적으로 전략적인 결정을 해야한다.
4.1.1. 테이블 형태별 적용기준
- 적은 데이터를 가진 소형 테이블
- 주로 참조되는 역활을 하는 중대형 테이블
- 업무의 구체적인 행위를 관리하는 중대형 테이블
- 저장용 대형 테이블
가) 적은 데이터를 가진 소형 테이블
- 적은 데이터의 의미: 한번의 다중 블록 I/O Call로 모든 데이터를 읽을 수 있는 경우((DB_FILE_MULTIBLOCK_READ_COUNT의 값보다 적은 테이블)
- 한번의 다중 블록 I/O Call로 모든 내용을 읽을 수 있으므로, 인덱스를 통한 스캔과 거의 차이가 없음. 그럼에도 불구하고 생성해야 하는가?
- 인덱스 유무는 옵티마이저의 판단에 많은 영향을 미치는데 특히 조인과 인덱스는 옵티마이저의 결정에 큰 영향을 미침
- 인덱스는 가장 큰 영향요소 이므로 존재 여부에 따라 실행 계획에 큰 영향을 미칠 수 있음.
- 해당 유형의 인덱스는 Nested Loop Join시 내측루프를 주로 수행하므로 많은 횟수가 수행될 수 있음. 약간의 차이가 전체적으로 큰 영향을 미칠 수 있음.
- 권고 : 작은 테이블이라도 PK는 반드시 생성을 권고하며, PK에 의해 참조가 많이 되는 테이블의 경우는 조인 시 효율을 위해 IOT 생성 검토도 필요
나) 주로 참조되는 역활을 하는 중대형 테이블
- 의미: 트랜잭션 데이터들의 행위의 주체나 목적이 되는 개체들로 구성된 테이블들. 모델링에서 키 엔티티로 분류되는 집합임.
- 특징: 좁은 범위의 스캔 또는 조인등에 의해 내측 루프에서 기본키에 의해 연결됨
검색 조건의 형태가 뚜렷하고, 데이터 증감이 별로 없으며, 검색 위주의 엑세스 발생
권고
- 기존의 사용중인 인덱스 블록에 사용하는 비율이 낮으므로, 대량 입력 작업이나 오랜 시간이 지났다면 인덱스 Rebuild 권고
다) 업무의 구체적인 행위를 관리하는 중대형 테이블
- 의미: 업무의 구체적인 내용을 담고 있는 테이블.
특징
- 조인에서 주로 외측 루프를 담당하고 있음.
- 테이블이 크고, 지속적으로 증가하고 있으므로 많은 인덱스는 입력 시 부하가 가게 하며, 인덱스 구성이 약간만 잘못 되어도 처리 범위가 증가할 수 있음.
- 다양한 엑세스 조건으로 인덱스의 수가 많고 복합 인덱스가 많으며, 다양한 연산자가 존재하여 결합 인덱스의 순서 또한 중요
권고
- 인덱스 구성 전략에 따라서 시스템이 미치는 영향이 크므로 절차를 충실히 따라야 함.
- 이를 위해 테이블에 엑세스 하고 있는 모든 유형을 수집하고, 앞으로 예상되는 형태까지 감안하는 것이 필요
라) 저장용 대형 테이블
- 의미: 로그성 데이터를 관리할 목적으로 생성된 테이블
- 특징: 대량의 데이터를 가지고 있으며, 지속적으로 대량의 데이터가 입력됨.
권고
- 갱신이 발생하지 않기 때문에 낮은 PCTFREE 값 지정하는 것이 공간 사용에 유리
- 기본키를 가지는 것은 입력 시 부담이 될 수 있으므로 사용하지 않는 것도 고려. 대신 Unique Index 생성 고려
- 테이블에 파티션을 만들고 파티션 마다 필요한 인덱스(Local Index)를 생성하는 것이 좋음. 오래된 데이터의 경우 파티션 단위로 떼어내기 쉽고 입력이나 검색 시 부담이 적어짐
- 파티션 인덱스 사용 시, 사용 파티션의 인덱스만 사용하는 것도 고려(전체 Local Index를 UNUSABLE 상태로 만든 후, 이후 필요한 파티션의 인덱스만 생성하는 방식)
4.1.2. 분포도와 손익 분기점
- 인덱스 생성의 목적: 전체 집합에서 범위를 줄여 선별된 부분만 엑세스 하고자 함
- 분포도: 전체 집합에서 해당 컬럼으로 조회 시 해당 조건이 차지하는 비율을 의미.
- 손익 분기점: 인덱스는 단일 블록 I/O를 유발하므로 분포도가 높은 경우에는 인덱스가 존재한다 할지라도 사용하지 않을 수 있다.
- 손익 분기점은 이렇게 인덱스 사용 여부를 결정하는 분포도 값이다. 옵티마이저는 손익분기점 이상이면 인덱스를 사용하지 않고 이하면 사용한다.
- 인덱스의 분포도가 높으면 무조건 인덱스를 생성하지 않는 것이 유리한가?
- 반드시 그렇지 않다. 부분 범위 처리를 할 경우 실제 분포도는 아주 낮아질 수 있다.
4.1.3. 인덱스 머지와 결합 인덱스 비교
- 인덱스 머지(Index Merge): 여러 인덱스가 협력하여 같이 엑세스를 주관
- 장점: 처리 범위가 넓은 경우, 테이블에 엑세스 하여 Filter 하는 부분이 생략됨. 비교하는 조건으로 인덱스만 사용.
- 결합 인덱스: 여러 컬럼을 모아 하나의 인덱스로 만드는 방식.
- 장점: 모든 조건이 인덱스 컬럼에 사용되는 경우 인덱스 머지에 비해 아주 효율적으로 수행될 수 있다.(단, 선두 컬럼의 Equal 연산에서만 적용)
- Index Merge 방식과 결합 인덱스 방식의 연산 차이
4.1.4. 결합 인덱스의 특징
- 인덱스의 첫 번째 컬럼이 조건절에 없다면 일반적으로 인덱스응 사용되지 않음(예외. Oracle 9i 이후 지원되는 Index Skip Scan의 경우는 가능)
- Equal 연산이 아닌 검색 조건이 들어오는 경우(범위 연산), 처리 범위가 크게 증가하여 효율이 크게 저하될 수 있음
가) 분포도와 결합 순서의 상관 관계
구성
- 테이블: TAB1, 컬럼: COL1, COL2
- 컬럼 COL1: 분포도가 좋지 않음
- 컬럼 COL2: 분포도가 좋음
- 사용된 SQL
SELECT * FROM TAB1
WHERE col1='A'
AND col2 between '113' and '115'
엑세스 방식에 따른 구분
- 분포도가 좋지 않은 COL1 컬럼을 복합인덱스의 선행 컬럼으로 설정한 경우 처리 과정(왼쪽 그림)
- col1='A' AND col2=112 인 데이터를 B-Tree 방식으로 바로 찾음
- ROWID를 이용하여 테이블 로우 엑세스
- 다음 로우를 탐색하여 조건에 만족하면 다시 테이블의 로우를 엑세스하고 그렇지 않으면 스캔 종료(이 경우, 한 번의 랜덤, 2개의 인덱스 로우 스캔)
- 분포도가 좋은 COL2 컬럼을 복합인덱스의 선행 컬럼으로 설정한 경우 처리 과정(오른쪽 그림)
- col2=112 AND col1='A' 인 데이터를 B-Tree 방식으로 바로 찾음
- ROWID를 이용하여 테이블 로우 엑세스
- 다음 로우를 탐색하여 조건에 만족하면 다시 테이블의 로우를 엑세스하고 그렇지 않으면 스캔 종료(이 경우, 한 번의 랜덤, 2개의 인덱스 로우 스캔)
- 결론: 인덱스의 모든 컬럼을 Equal 연산으로 처리한 경우 처리량에는 차이가 없음. 단지 Equal 연산만 사용했으므로 필요한 데이터만 읽을 수 있게 되었기 때문.
나) 이퀄(=)이 결합순서에 미치는 영향
- 실제 실무에서는 Equal 연산만으로 처리되지 않고, 다양한 범위 처리 연산(LIKE, BETWEEN, < > 등)이 사용됨
- 인덱스의 선행 컬럼에 대해 Equal 연산이냐 아니냐는 처리 범위에 크게 영향을 미침
구성
- 테이블: TAB1, 컬럼: COL1, COL2
- 컬럼 COL1: 분포도가 좋지 않음
- 컬럼 COL2: 분포도가 아주 좋음
- 사용된 SQL
SELECT * FROM TAB1
WHERE col1='A'
AND col2 between '113' and '115'
엑세스 방식에 따른 구분
분포도가 좋지 않은 COL1 컬럼을 복합인덱스의 선행 컬럼으로 설정한 경우 처리 과정(왼쪽 그림)
- col1='A' AND col2=113 인 첫번째 로우를 찾는다.
- ROWID를 이용하여 테이블의 로우를 엑세스 한다.
- 다음 로우를 차례로 스캔하면서 col1 !='A' OR col2 > 115 일 때 까지 테이블의 로우를 엑세스 하고 그렇지 않으면 처리를 종료한다.
- 이 경우, 첫 번째 컬럼이 Equal 연산이고 두 번째 컬럼에는 정렬이 되어 있으므로 between이 들어갔다 하더라도 필요한 엑세스만 하게 된다.
분포도가 좋은 COL2 컬럼을 복합인덱스의 선행 컬럼으로 설정한 경우 처리 과정(오른쪽 그림)
- col2=113 AND col1='A' 인 첫번째 로우를 찾는다.
- ROWID를 이용하여 테이블의 로우를 엑세스 한다.
- col2 > 115 일 때 까지 계속해서 스캔한다. 스캔한 로우는 col1='A' 인지 체크하여 성공하면 ROWID를 이용하여 테이블을 엑세스한다.
- col2 > 115 이면 처리를 종료한다.
- 이 경우, col2 에 대해서는 체크만 하는 이유는 이 컬럼에 대해서는 정렬이 되어있지 않기 때문. 체크로 인해 ROWID를 이용한 테이블 엑세스만 줄어들 뿐이다.
- 아래의 경우에서 col1 컬럼에 대해서만 인덱스가 있는 경우에서 차이를 볼 수 있다.
- 11번의 ROWID 스캔에서 3번의 ROWID 스캔으로만 줄고, 실제 인덱스 내부 처리 범위내에서는 효율을 보지 못했다.
결론
- 인덱스의 처리 범위를 고려해야 하며 컬럼의 분포도를 고려한 인덱스 컬럼 선정 방식은 맞지 않다.
- 조회 시 사용되는 컬럼에 Equal를 많이 쓰는 경우 처리 범위를 크게 줄여주므로 해당 컬럼을 인덱스 선행 컬럼으로 두는 것이 올바르다.
다) IN 연산자를 이용한 징검다리 효과
적용 예
- 비효율적인 인덱스가 이미 큰 테이블에 대해 사용하고 있는 경우 ( 위 예에서 col2, col1 순으로 생성된 결합 인덱스)
- 올바르게 컬럼 순서로 생성된 인덱스의 쿼리 유형에 상반되는 컬럼 순서의 쿼리가 가끔 사용되는 경우 ( col1(=), col2(between) 순서로 들어오는 쿼리가 대부분이고 인덱스고 그 순서로 생성되어있는데, 가끔 col2(=), col1(between) 과 같은 쿼리도 수행되는 경우)
- 이 경우, 새롭게 인덱스를 생성하는 것은 인덱스의 중복 투자이므로 올바르지 않음. IN 연산자를 통해 기존 인덱스 만으로도 효율적인 결과를 가져올 수 있음
사용 예제
기존의 between 연산을 이용한 경우(왼쪽 그림)
- col2 컬럼 기준으로 넒은 범위 스캔을 한다. col1 컬럼의 필요한 컬럼인 'A'만을 뽑아내지 못한다. 이 경우, 범위에 해당되는 모든 인덱스를 읽으므로 선을 그은것과 같다 하여 '선(line)연산' 이라고도 한다.
IN 연산을 이용한 경우(오른쪽 그림)
- INLIST ITERATOR(111,112)
- 1. col2=:value AND col1='A' 인 첫번째 로우를 찾는다. 이 때, 인덱스 트리를 탐색하는 과정이 포함된다.
- 2. ROWID 탐색을 하고 테이블의 데이터를 뽑아낸다.
- 3. col2!=:value OR col1!='A' 일 때 까지 테이블의 로우를 엑세스하고 만족하지 않으면 다음의 Iterator 값을 뽑아내 1번 과정을 반복한다.
- 위 연산은 IN이 가지는 연산의 특징으로 col2 , col1 컬럼의 equal 연산을 여러번 수행하여 불필요한 인덱스 값을 읽는 것을 방지한다.
- IN 리스트 내부에 있는 데이터들로 인해 필요한 인덱스 값만 읽게 되는데, 해당 인덱스에 점을 찍은것과 같다하여 '점(point)연산' 이라고도 한다.
- 위 IN 리스트를 사용한 쿼리는 다음의 OR를 사용한 쿼리와 거의 동일한 수행방식을 가진다.
SELECT *
FROM TAB1
WHERE (COL2=111 AND COL1='A') OR (COL2=112 AND COL1='A')
라) 처리 범위에 직접적인 영향을 주지 못하는 컬럼의 추가 기준
- 결합 인덱스를 사용하는 쿼리 내부에 equal 연산을 사용하지 않는 컬럼 이후로는 범위를 줄여주지 못함.
- (예로써, (A,B,C,D)로 구성된 인덱스에 A(=),B(between),C(=),D(=) 와 같이 사용했을지라도 B 연산에서 범위 연산자를 쓰게 됨에 따라 C,D 컬럼은 인덱스 스캔 범위를 줄여주지 못함)
ex) 테이블 구성
- col1: equal(=) 연산이 사용됨.
- col2: 사용되지 않거나, 범위 연산자(like, between, < , > 등)이 사용됨.
- col3: 다양한 처리 연산이 사용됨
- 사용 쿼리
SELECT * FROM TAB1
WHERE A='2' AND C='61'
사용 예제
(A+B) 컬럼에 복합인덱스를 만든 경우(왼쪽 그림)
- 1. A 컬럼에 대해서는 인덱스가 존재하므로 A='2' 인 모든 노드를 탐색한다.
- 2. 그러나 C 컬럼에는 인덱스가 없으므로 ROWID를 통한 테이블 억세스으로 테이블 데이터에서 C 컬럼을 뽑아내 C='61' 것을 필터링 한다.
- 3. 테이블 내부에서 필터링해서 조건에 맞는 것만 출력한다. 이 과정은 인덱스 스캔이 종료될때 까지 계속 수행된다.
- 인덱스 탐색 결과 나온 5건에 대해 모두 ROWID를 통한 테이블 엑세스를 한다. 위 경우 총 5번의 테이블 스캔을 한다.
(A+B+C) 컬럼에 복합인덱스를 만든 경우(오른쪽 그림)
- 1. A 컬럼에 대해서는 인덱스가 존재하므로 A='2' 인 모든 노드를 탐색한다.
- 2. 앞선 B 컬럼의 검색 조건 부재로 C 컬럼이 인덱스 검색 범위를 줄여주진 못하나, 값은 존재하므로 C='61' 인 것을 필터하는 부분을 인덱스 내부에서 해결한다.
- 3. 인덱스 내부에서 필터링해서 조건에 맞는 것만 ROWID를 통한 테이블 억세스로 값을 뿌려준다.
- 인덱스 탐색 결과 나온 5건에 대해 필터를 통해 걸리진 1건에 대해서만 ROWID를 통한 테이블 스캔을 한다. 위 경우 총 1번의 테이블 스캔을 한다.
4.1.5. 결합 인덱스의 컬럼 순서 결정 기준
컬럼 순서를 결정하는 우선 순위
- 1단계: 항상 사용하는가?
- 2단계: 항상 '='로 사용하는가?
- 3단계: 어느 것이 더 좋은 분포도를 가지는가?
- 4단계: 자주 정렬되는 순서는 무엇인가?
- 5단계: 부가적으로 추가시킬 컬럼은 어떤 것으로 할 것인가?
- 상황 가정 \ : C1, C2, C3, C4 컬럼들에 대해 복합인덱스 컬럼 순서를 어떻게 결정할 것인가?
- 아래는 쿼리가 사용하고 있는 쿼리 조건의 목록임
1. C1(=), C2(BETWEEN), C3(=)
2. C2(=), C3(BETWEEN), C4(>)
3. C1(=), C2(=), C3(LIKE)
4. C1(=), C2(=), C4(>)
1단계: 항상 사용하는가?
- 컬럼의 사용 횟수: C2(4회), C1(3회), C3(2회), C4(2회)
- 추가 가정: C1 컬럼의 카디널러티가 낮아서 해당 컬럼이 없는 경우에 대해서는 Index Skip Scan 사용하도록 가정
- 두 번째 경우에서 C2의 경우에서 Equal 연산이 사용되므로 C1 케이스에서 \+1 해서 총 4회 사용으로 가정
- 최종 후보: C1, C2
2단계: 항상 '='로 사용하는가?
- Equal 연산 사용 횟수: C1(3회), C2(3회)
- C2 컬럼의 경우 첫 번째 경우에서 Between 연산을 사용하므로
- 결과: C1+C2
3단계: 어느 것이 더 좋은 분포도를 가지는가?
- 분포도를 고려 및 사용 가능한 추가 연산 형태(예로써 Between을 IN으로 변환 가능한 경우) C1, C2 컬럼의 순서를 추가 검토
- 이후에 발생할 상황 추이 후 검토
- 엑세스 형태를 수집할 때 현재 사용하고 있는 인덱스 뿐만 아니라 앞으로 등장할 것으로 예측되는 엑세스 형태도 같이 추출
- 앞으로 어떤 컬럼이 Equal 연산 외에 다른 연산을 사용할 지 검토
4단계: 자주 정렬되는 순서는 무엇인가?
- 정렬을 요구하는 구문의 사용 시, 정렬 순서 조사 후 검토. 정렬 시 앞단에 나오는 컬럼을 우선적으로 두는 것이 맞다.
5단계: 부가적으로 추가시킬 컬럼은 어떤 것으로 할 것인가?
- C3, C4 컬럼의 경우 모든 조건들이 처리 범위를 줄여주는 형태는 아님. C3, C4간의 우선 순위 선정 필요
- 1. C1(=), C2(BETWEEN), C3(=) : C3이 C4 앞에 오는 것이 유리
- 2. C2(=), C3(BETWEEN), C4(>): 순서 관계 없음
- 3. C1(=), C2(=), C3(LIKE): C3이 C4앞에 오는 것이 유리
- 4. C1(=), C2(=), C4(>): C4가 C3 앞에 오는 것이 유리
- 위의 단순한 결과대로라면 (C1+C2+C3+C4)의 순으로 인덱스 생성하는 것이 좋음
- 그러나, 4 의 경우가 빈번하게 엑세스 되는 경우라면 (C1+C2+C4) 인덱스를 추가 생성해야할 필요도 있을 것임
- 이 이외에 C3, C4 컬럼의 분포도 또한 고려해서 전체적인 상황을 살펴 결정하는 것이 필요
4.1.6. 인덱스 선정 절차
가) 테이블의 엑세스 형태를 최대한 수집
개발 단계에서의 엑세스 형태 수집
- 1) 반복 수행되는 엑세스 형태를 찾는다. 반복 수행되는 엑세스는 자신의 수행속도에 반복횟수를 곱한 만큼의 부하를 가져오므로 수행속도에 미치는 영향이 아주 크다.
- Nested Loop Join, Sub-Query, Fetch후 루프 내에서 반복되는 쿼리
- 2) 분포도가 아주 양호한 컬럼들을 발췌하여 엑세스 유형을 조사한다. 테이블에는 아주 양호한 분포도를 가진 컬럼이 있기 마련이다.
- 인덱스 컬럼 순서를 정할 때등 여러 경우에서 크게 활용될수 있음
- 3) 자주 넒은 조건이 부여되는 경우를 찾는다. 인덱스는 넓은 범위를 처리하게 될 때 많은 부담을 주게 된다.
- - 전체 범위 처리 시, 넓은 범위 처리는 인덱스 사용 때 수행속도가 좋지 않을 수 있음.
- - 처리 범위의 최대 크기와 평균 예상 범위, 자주 사용되는 정렬의 순서, 처리 유형을 수집하면 유용한 자료가 될 것임
- 4) 조건에 자주 사용되는 주요 컬럼들을 추출하여 엑세스 유형을 조사한다. 빈번하게 사용된다는 것은 시스템 전반에 미치는 영향이 그 만큼 크기 때문에 아주 중요하다.
- 5) 자주 결합되어 사용되는 컬럼들의 조합 및 정렬되는 순서를 조사한다. 업무적인 측면에서 각 컬럼들간의 상호관계를 잘 파악해 보면 특정 컬럼들끼리 자주 조합하여 사용되는 경합형태를 찾을 수 있다.
- 중심이 되는 컬럼을 찾아 이와 연관되는 컬럼들을 검토
- 6) 역순으로 정렬되어 있는 경우를 찾는다. End User는 조건의 범위는 넓게 부여하면서 최근의 데이터만 보려고 하는 경우가 많음. 빠른 응답까지 요구함
- 7) 통계 자료 추출을 위한 엑세스 유형을 조사한다. 통계자료를 추출하는 경우는 대개 범위가 넓다.
- 넓은 범위 처리가 대부분 임. 클러스터나 잘 조합된 결합 인덱스 이용하는 것이 좋음.
운영 단계에서의 엑세스 형태 수집
- 시점: Test 단계 또는 정상 가동 중인 시스템의 인덱스 교정 시점
- 1) 어플리케이션 소스 코드에서 SQL을 추출하여 분석용 테이블에 보관한다.
- 기능: 어플리케이션을 분석하여 SQL 문장을 Repository 에 저장. 손쉽게 SQL 문장을 가져올 수 있음.
- 한계: 동적 SQL 과 같은 쿼리는 가져오는데 한계가 있으며, 수행 횟수와 같은 자세한 사항은 알 수 없음
- 2) SQL-Trace 파일을 파싱하여 SQL 문장 뿐만 아니라 실행계획, 현재 적용되고 있는 인덱스 , 실행 횟수, 처리 범위등의 매우 상세한 정보 획득할 수 있다.
- 기능: 전체 커다란 trace 결과에 대해 하나의 상세한 레포트도 얻을 수 있으며 상용 SW에 따라 Advice 역할 까지 해주기도 함.
- 한계: 시스템에 큰 부하를 줌. 그러므로 trace 기간은 제한 되어야 하며 그 기간내의 분석 밖에 행할수 없음
- 3) 공유 SQL 영역에서 직접 SQL을 찾아오는 방법은 보다 SQL 수집을 간편하게 한다.
- 기능: 서버에 부담을 덜 주므로 장기간 수집하는 것이 가능하다.
- 단점: trace에 비해 정보가 빈약하다. 어떤 어플리케이션에서 수행되었는지와 같은 장기간 수집을 하더라도 여전히 모든 SQL 구문 수집하는 것이 어렵다.
수집된 SQL을 테이블 별로 출력하여 엑세스 형태 기록
- 유사한 형태의 SQL들이 정렬되도록 출력
- SQL문장 별로 정렬하는 것 보다 조건절에 사용된 컬럼별로 정렬하는 것이 보다 유리
나) 인덱스 대상 컬럼의 선정 및 분포도 조사
인덱스 대상 컬럼 기준
- 엑세스 유형에 자주 등장하는 컬럼
- 인덱스의 앞부분에 지정해야 할 컬럼
- 기타 수행속도에 영향을 미칠 것으로 예상되는 컬럼
인덱스 대상 컬럼을 선정하고 분포도를 분석한 사례
|
<그림 1-4-9> |
- 매출번호(SALENO): 3년동안 몇건이 발생할 것인지 예상한다.과거 발생자료를 이용한 통계자료 추출 혹은 현업담당자와 협의.
- 판매일자(SALEDATE): 앞서 예상한 월평균 발생건수를 토대로 함.혹은 3년중 휴일을 제외한 날짜를 계산 한 후 총로우수로 나눔. 최대치를 찾는다.
- 판매부서(SALEDEPT)+판매일자: 3년간의 데이터를 부서로 나누어 평균을 산출. 최대, 최소치를 구한다.
- 진행상태(STATUS): 몇가지 종류인지, 어떤 상태에 데이터가 몰려있는지 조사한다.
- 위와같이 하여 최대치와 평균치의 차이가 심하다면 '특기사항'란에 기입한다.
|
<그림 1-4-10> |
다) 특수한 액세스 형태에 대한 인덱스 선정
- 반복되는 액세스형태를 찾아낸다.
- '항상사용되느냐','항상=로 사용되느냐'
- 동률이라면 분포도가 좋은 것이 앞에 오는 것이 유리.
- 1번 액세스 형태인 SALENO+SALEDATE 를 검토해 보면 둘 다 =로 사용되기 때문에 분포도나 정렬 순서를 고려해서 결정하면 된다.
- 7번 및 11번 액세스 형태를 감안한다면 항상 사용되는 것은 ITEM이다.
- SALENO는 1번 액세스에서만 사용되는 것으로 조사되었지만, 혼자서만 사용될 가능성이 높음. 따라서 선두 컬럼에서 배제하기는 어렵다.
- ITEM은 좋은 분포도를 가지고 있고, 업무적으로도 중요하며, 앞으로도 자주 사용될 것으로도 보인다.(??)
- 또한 SALENO 없이도 사용되는 경우가 많으므로 독립된 인덱스에서 선행컬럼이 될 자격을 갖추고 있다.
- 11번 액세스에서 ITEM은 주도적인 역할을 하는 것으로 보이진 않으므로 특별한 역할을 부여할 필요는 없어보인다.
- CUSTNO는 평균이 63에 불과하고, 최대가 300 정도이며, 범위처리를 하는 경우가 거의 없이 =로 사용되고 있으므로 CUSTNO 혼자 만으로도 확실한 수행속도를 보장 받을 수 있을 것으로 보임.
- 현재보다 현격하게 데이터량이 증가할 것으로 보인다면 SALEDATE를 인덱스에 추가시키는 것을 검토한다.
라) 클러스터링 검토
- 넓은 범위의 데이터가 자주 액세스 되어 별도의 집계 테이블을 만들지 않고서는 다른 방법이 없는 경우에는 주로 클러스터링을 사용한다.
- 클러스터링은 인덱스와는 달리 분포도가 넓은 것이 유리하다.
- 검색의 속도를 향상시켜주며, 입력,수정,삭제시에는 부하를 준다.
마) 결합인덱스 구성 및 순서의 결정
그룹1
5 SALEDATE(like),STATUS(=60),CUSTNO(like)
8 SALEDATE(like),STATUS(=),group by CUSTNO
6 STATUS(in),[AGENTNO(like)]
- 가장 선두에 와야 할 컬럼은 STATUS 임.
- 방법1: STATUS+SALEDATE, STATUS+AGENTNO (두개의 인덱스 생성)
- 방법2: STATUS+SALEDATE+AGENTNO (1개의 인덱스 생성)
그룹2
7 ITEM(=),SALEDATE(like),SALEDEPT(like)
11 AGENTNO(=),SALEDATE(between),ITEM(like)
- 항상 사용되는 컬럼음 ITEM,SALEDATE 임.
- =로 사용되는 것까지 고려한다면 ITEM+SALEDATE 여야 함.
- 11번의 액세스는 만족스럽지 못하므로 AGENTNO+SALEDATE로 구성된 인덱스를 생성하는 것이 바람직함.
- (인덱스 생성의 부담이 있더라도 새로운 인덱스를 생성하는 것을 권장함.)
|
<그림 1-4-12> |
- 모든 액세스에 만족표시(★)가 되도록 한다면 목표달성.
바) 시험생성 및 테스트
- 인덱스 전략이 새롭게 수립되었다면 테스트 과정을 거치는 것이 바람직하다.
- 테스트시 예상했던 실행계획이 쉽게 나타나지 않는다거나, 특정 액세스 형태에 사용해야 할 인덱스를 분명하게 하기 위해서 힌트를 사용해야 한다면 주의사항이 기록한다.
사) 수정이 필요한 애플리케이션 조사 및 수정
- 힌트사용, 인덱스 사용제한, 해제 시키는 수정 필요.
아) 일괄적용
- SQL의 수정과 인덱스의 변경을 동시에 일괄적으로 적용해야 한다.