이전글 : https://sewonzzang.tistory.com/38
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. 자동 형변환
'database' 카테고리의 다른 글
[SQL] UNION / UNION ALL, WITH (0) | 2022.02.07 |
---|---|
[SQL] 윈도우 함수 (WINDOW FUNCTION) (0) | 2022.02.05 |
[SQL] 인덱스(Index) - (2) 인덱스 기본 사용법 - 2 (0) | 2022.01.26 |
[SQL] 인덱스(Index) - (2) 인덱스 기본 사용법 - 1 (0) | 2022.01.25 |
[SQL] 인덱스(Index) - (1) 미리보는 인덱스 튜닝 (0) | 2022.01.22 |
댓글