인덱스의 기본 사용법은 인덱스를 Range Scan 하는 방법을 의미한다.

 

인덱스 컬럼(선두 컬럼)을 가공하지 않아야 인덱스를 정상적으로 사용할 수 있다.

Index Range Scan은 리프 블록에서 스캔 시작점을 찾아 거기서부터 스캔하다가 중간에 멈추는, 즉 리프 블록 일부만 스캔한다.

Index Full Scan 은 스캔 시작점을 찾을 수 없고 멈출 수 도 없어 리프 블록 전체를 스캔하는 것이다.

 

LIKE

where 이름 like '이%' 는 Range Scan이 가능하지만 

where 이름 like '%이'where 이름 like '%이%'는 시작범위 끝범위를 찾을 수 없기 때문에 Range Scan 할수없다.

OR

where (전화번호 like '010%' or 이름 like  '이%') 역시 시작 지점을 찾을 수 없기 때문에 Range 스캔할 수 없다.

이럴땐 OR Expansion을 사용한다.

Select *
FROM 고객
WHERE 전화번호 like '010%'
union all
Select *
FROM 고객
WHERE 이름 like '이%'

SELECT /*+ use_concat */ * FROM 고객
where (전화번호 like '010%' or 이름 like  '이%')  
이 SQL이 CONCATENATION가 실행계획에 나타나면

이러면 Index Range Scan을 활용할 수 있다.

IN

IN역시 OR 조건을 표현하는 다른 방식이므로 위와 같이 UNION ALL 방식으로 작성한다.

그래서 SQL 옵티마이저가 IN-List Iterator 방식을 사용하여 IN-List 개수만큼 Index Range Scan을 반복한다.

 

가장 중요한것은

선두컬럼 인덱스가 가동되면 안되는것이다. 선두컬럼 인덱스만 가공안되면 무조건 Index Range Scan 가능하다.

 

Index Range Scan탄다고 성능이 좋은건 아니다. (이건 3장에서)

인덱스는 정렬되어있으므로 소트 연산을 생략할 수도있다. (오름차순, 내림차순 모두 가능)

 

ORDER BY 절에서 컬럼 가공

조건절이 아닌 ORDER BY 또는 SELECT-LIST에서 컬럼을 가공함으로 인해 인덱스를 정상적으로 사용할 수 없는 경우도 있다.

 

SELECT *
FROM 상태변경이력
WHERE 장비번호 = 'C'
ORDER BY 변경일자 || 변경순번

이러면 정렬 연산을 생랼할 수없다. 가공한 값 기준으로 정렬해달라고 했기때문에

 

SELECT-LIST에서 컬럼가공

SELECT에서 MAX나 MIN값을 할때 정렬연산을 따로 할 필요가 없다. 수직적 탐색을 통해 조건을 만족하는 가장 왼쪽이 MIN이고 DESCENDING이면 가장 오른쪽이다. 근데 이 값을 가공하면 정렬 연산을 생략할 수 없다.

 

자동 형변환

오라클에서 숫자형과 문자형이 만나면 숫자형이 이긴다. 숫자형 컬럼 기준으로 문자형 컬럼을 변환한다는 것

LIKE 연산자면 문자열 비교 연산자이므로 문자형 기준으로 숫자형 컬럼이 변환한다.

TO_CHAR, TO_DATE, TO_NUMBER 같은 애들은 아무리 해도 성능에 별 영향이 없다. 생략한다고 해도 옵티마이저가 알아서 하기 때문에 연산횟수가 줄어드는것도 아니다.

'SQLP > SQLP' 카테고리의 다른 글

3-1. 테이블 액세스 최소화  (0) 2025.01.16
2.3 인덱스 확장기능 사용법  (0) 2025.01.15
2-1. 인덱스 구조 및 탐색  (0) 2025.01.13
1-3. 데이터 저장 구조 및 I/O 매커니즘  (0) 2025.01.12
1-2. SQL 공유 및 재사용  (0) 2025.01.11

+ Recent posts