database

[SQL] 인덱스(Index) - (2) 인덱스 기본 사용법 - 3

sewonzzang123 2022. 1. 27.
반응형

 

 

이전글 : https://sewonzzang.tistory.com/38

 

[SQL] 인덱스(Index) - (2) 인덱스 기본 사용법 - 2

이전 글 : https://sewonzzang.tistory.com/37 [SQL] 인덱스(Index) - (2) 인덱스 기본 사용법 - 1 이전 글: https://sewonzzang.tistory.com/34 [SQL] 인덱스(Index) - (1) 미리보는 인덱스 튜닝 sql관련 글들..

sewonzzang.tistory.com


 

6. SELCET-LIST에서 컬럼 가공

 

인덱스를 [장비번호 + 변경일자 + 변경순번] 순으로 구성하면, 아래와 같이 변경순번 최소 값을 구할 때도 옵티마이저는 정렬 연산을 따로 수행하지 않습니다. 수직적 탐색을 통해 조건을 만족하는 가장 왼쪽 지점으로 내려가서 첫 번째 읽는 레코드가 바로 최소값이기 때문입니다.

SELECT MIN(변경순번)
FROM 상태변경이력
WHERE 장비번호 = 'C'
AND 변경일자 = '20180316'

 

만약, 변경순번 최대값을 구할 때(MAX(변경순번))는 어떨까요? 마찬가지로 정렬 연산을 수행하지 않습니다. 최소값을 찾아 수직적 탐색할 때 왼쪽으로 내려갔지만, 최대값을 찾을 때는 오른쪽으로 내려가는 점만 다릅니다.

수직적 탐색을 통해 조건을 만족하는 가장 오른쪽 지점으로 내려가서 첫 번째 읽는 레코드가 바로 최대값 입니다.

 

인덱스를 이용해 이처럼 정렬 연산 없이 최소 또는 최대값을 빠르게 찾을 때 아래와 같은 실행계획이 나옵니다.

실행방식은 실행계획에 표현돼 있는 그대로 입니다. 인덱스의 리프 블록의 왼쪽(MIN) 또는 오른쪽(MAX)에서 레코드 하나(FIRST ROW)만 읽고 멈춥니다.

ROWS Row Source Operation
---- ----------------------------
0	STATEMENT
1	SORT AGGRANGE
1	FIRST ROW
1	INDEX RANGE SCAN (MIN/MAX) 상태변경이력_PK

 

그런데 만약 SQL을 아래와 같이 작성하면 어떻게 될까요? 정렬 연산을 생략 할 수 없습니다. 인덱스에는 문자열 기준으로 정렬돼 있는데, 이를 숫자값으로 바꾼 값 기준으로 최종 변경순번을 요구했기 때문입니다.

 

SQL을 아래와 같이 바꾸면 정렬 연산 없이 최종 변경순번을 쉽게 찾을 수 있습니다. 물론 이렇게 변환하려면 변경순번 값이 고정너비로 입력돼있어야 합니다. 애초에 변경순번 데이터타입을 숫자형으로 설계했다면 튜닝할 일이 없었을 것 입니다.

// 바꾸기 전
SELECT NVL(MAX(TO_NUMBER(변경순서)),0)
FROM 상태변경이력
WHERE 장비번호 = 'C'
AND 변경일자 = '20180316'

ROWS   Row Source Operation
------ --------------------
0	 STATEMENT
1	 SORT AGGREGATE
131577 INDEX RANGE SCAN 상태변경이력_PK

// 바꾼 후
SELECT NVL(TO_NUMBER(MAX(변경순서)),0)
FROM 상태변경이력
WHERE 장비번호 = 'C'
AND 변경일자 = '20180316'

ROWS   Row Source Operation
------ --------------------
0	   STATEMENT
1	   SORT AGGREGATE
1	   FIRST ROW
1	   INDEX RANGE (MIN/MAX) SCAN 상태변경이력_PK

 // TODO

 

 

7. 자동 형변환

반응형

댓글