인덱스를 활용하여 데이터를 읽을 때에는 여러 방식이 있다.

어떤 상황에 어떤 스캔을 하고, 효율적으로 인덱스를 사용하기 위해서는 이를 알아둘 필요가 있다.

기본적으로 수직 탐색 후 수평 탐색, 그리고 테이블 I/O의 과정을 거쳐 데이터 레코드를 가져오게 된다.

B*Tree 인덱스의 가장 일반적이고 정상적인 형태의 액세스 방식이다. 루트에서 리프 블록까지 수직적으로 탐색한 후에 ‘필요한 범위’만 스캔한다.
Index Range Scan을 사용하려면
하지만, Range Scan이 중요한 것이 아니라, 성능은 인덱스 스캔 범위, 테이블 액세스 횟수를 얼마나 줄일 수 있느냐로 결정된다.

수직적 탐색 없이 인덱스 리프 블록을 처음부터 끝까지 수평적으로 탐색하는 방식이다.
idx (ename, sal)
----
SELECT * FROM emp
WHERE sal > 2000
ORDER BY ename;
Index Full Scan의 효용성
인덱스 스캔 단계에서 대부분 레코드를 필터링하고 아주 일부만 테이블을 액세스하는 상황이라면, 면적이 큰 테이블보다 인덱스를 스캔하는 쪽이 유리하다.

전체 범위 처리:
- 모든 데이터를 읽고 정렬
- 그 다음 LIMIT 적용
- 100만 건 정렬 후 100건 추출 ❌
부분 범위 처리:
- 정렬된 상태로 읽으면서
- 필요한 만큼만 읽고 즉시 종료
- 100건만 읽고 종료 ✅ 결국, 정렬과 LIMIT !인덱스 풀 스캔 vs 테이블 풀 스캔

수직적 탐색만으로 데이터를 찾는 스캔 방식으로, Unique 인덱스를 ‘=’ 조건으로 탐색하는 경우에 작동한다.

루트 또는 브랜치 블록에서 읽은 컬럼 값 정보를 이용해 조건절에 부합하는 레코드를 포함할 ‘가능성이 있는’ 리프 블록만 골라서 액세스하는 스캔 방식이다.
select * from emp where sal between 2000 and 4000;Index Skip Scan 작동 조건
선두 컬럼이 조건절에 없고, 후행 컬럼이 조건절에 있을 때
선두 컬럼에 대한 조건절은 있고, 중간 컬럼에 대한 조건절이 없는 경우
idx (c1, c2, c3)
----
SELECT * FROM ?
WHERE c1 = 1
AND c3 BETWEEN '19990101' AND '19990131'
c3 기준 선행 컬럼 c2가 없다고 생각해도 좋을 듯!
idx (c1, c2, c3)
----
SELECT * FROM ?
WHERE c3 BETWEEN '19990101' AND '19990131'
또한, c1, c2 모두 조건절에 없는 경우에도 유용하게 사용할 수 있음
선두 컬럼이 부등호, BETWEEN, LIKE같은 범위 검색 조건인 경우
idx (날짜, 유형 코드)
----
SELECT * FROM ?
WHERE 날짜 BETWEEN '19990101' AND '19990131'
AND 유형 코드 = '01'
Index Range Scan이 불가능하거나 효율적이지 못한 상황에서 Index Skip Scan이 종종 빛을 발한다. 부분 범위 처리가 가능하다면 Index Full Scan이 도움 되기도 한다.
Index Skip Scan은 사용하는 것만이 아니라 선두 컬럼과 후행 컬럼의 Distinct Value 개수가 중요하다는 점 잊지 말 것 !
기본적으로 최적의 Index Range Scan을 목표로 하되, 이 방법이 오히려 비효율적일 때 이러한 스캔 방식을 차선책으로 활용하는 것이 바람직하다.
논리적인 인덱스 트리 구조를 무시하고, 인덱스 세그먼트 전체를 Multiblock I/O 방식으로 스캔하는 방식이다.
특징

Index Range Scan과 기본적으로 동일한 스캔 방식이다. 내림차순으로 정렬된 결과 집합을 얻는다는 점만 다르다.
등의 상황에서 사용되곤 한다.