본문 바로가기
데이터베이스

Oracle 인덱스 스캔 방식2: Index Skip Scan, Full Scan, Fast Full Scan

by 데이널 2024. 5. 28.

이전 포스팅에서 인덱스 스캔 방식 중 Index Range Scan, Index Range Scan Descending 및 Index Unique Scan에 다뤘습니다. 이번 글에서는 나머지 방식인 Index Skip Scan, Index Full Scan, Index Fast Full Scan에 대해서 설명해 보겠습니다. 
 

 

Index Skip Scan

일반적인 인덱스 액세스는 수직적인 탐색과 수평적인 탐색이 반드시 각각 1회만 수행하는데요. Index skip scan은 수직적인 탐색과 수평적인 탐색이 반복되어 수행되는 액세스 방식입니다.

결합 인덱스의 선행 열을 사용하지 않고 두번째 인덱스 항목으로 액세스 하는 방식입니다. 이 방법의 장점은 선행 열이 쿼리에 지정되지 않은 경우에도 인덱스를 사용할 수 있다는 것인데요. 이는 선행 열의 카디널리티가 낮은 경우 특히 유용할 수 있습니다.

쉽게 말해 선행 칼럼의 Distinct Value가 작을 때 효율적이라는 이야기 입니다. 예를 들어, 남/녀, 동/서/남/북 같은 컬럼들이 있겠네요. 선행 칼럼이 부정형 조건, NULL, NOT NULL인 경우도 가능합니다. 
 

Index Skip Scan
Index Skip Scan

1. 작동 방식

  • 데이터베이스는 선행 열을 건너뛰고 인덱스의 나머지 열을 사용하여 관련 행을 찾습니다.
  • 선행 열의 고유 값을 기반으로 인덱스를 논리적으로 더 작은 섹션으로 나눕니다. 
  • 그리고 각 섹션에서 다른 열의 지정된 값을 검색합니다.

2. 예시 쿼리와 실행계획

1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT /*+ index_ss(a 직원_X02) */ * 
FROM 직원 a
WHERE 입사일자 = :VAL
;
 
인덱스 02: 지역 + 입사일자
 
Execution Plan
-----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=ALL_ROWS 
   1    0   TABLE ACCESS (BY INDEX ROWID) OF '직원' (TABLE)
   2    1     INDEX (SKIP SCAN) OF '직원_X02' (INDEX)
 
cs

 
 

Index Full Scan

인덱스 전체 스캔은 데이터베이스가 인덱스의 모든 항목을 스캔해야 하는 경우에 사용됩니다. 이 방법은 인덱스 자체에 필요한 모든 열이 포함되어 있어야만 사용할 수 있습니다. 전체 테이블 스캔을 피하고 인덱스만 스캔해 합니다. 이는 대규모 데이터 세트를 검색하는 데 효율적일 수 있습니다.
 
인덱스 작동 원리는 트리 구조에 대해 Root Node가 가리키는 가장 왼쪽 자식(LMC)의 Branch Node를 거쳐 그 Branch Node가 가리키는 가장 왼쪽(LMC)의 Leaf Node까지 수직적인 탐색을 합니다. 그 이후에 수평적인 내림차순 탐색을 통해 가장 마지막 Leaf Node까지 양방향 Linked List를 따라 액세스 하는 방식입니다. 

역시 Single Block I/O가 발생되며 인덱스 Leaf Node의 Entry들의 정렬된 결과를 얻게 됩니다. 
 

Index Full Scan
Index Full Scan

1. 작동 방식

  • 데이터베이스는 인덱스의 모든 항목을 순차적으로 읽습니다.
  • 이 방법은 전체 테이블 스캔과 유사하지만 인덱스가 테이블보다 작거나 인덱스에 쿼리에 필요한 모든 열이 포함된 경우 더 빠를 수 있습니다.

 

2. 예시 쿼리와 실행계획

1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT /*+ index(a 직원_X03) */ * 
FROM 직원 a
WHERE 지역 = :VAL 
AND 입사일자 > 20240101 
;
 
인덱스 03: 입사일자
 
Execution Plan
-----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=ALL_ROWS 
   1    0   TABLE ACCESS (BY INDEX ROWID) OF '직원' (TABLE)
   2    1     INDEX (FULL SCAN) OF '직원_X03' (INDEX)
cs

 

Index Fast Full Scan

Index Fast Full Scan은 Index Full Scan과 유사할 것 같지만 오히려 FULL 테이블 스캔과 더 유사하게 작동합니다. 인덱스의 모든 블록을 읽으므로 특히 대규모 인덱스의 경우 일반 인덱스 스캔보다 속도가 빠릅니다. 이 방법은 성능을 향상하기 위해 병렬 힌트와 같이 사용됩니다.
 
이 스캔 방식의 특징은 인덱스의 논리적 구조가 아닌 물리적 저장순서대로 인덱스 블록을 읽어들입니다. Root Block과 Branch Block은 액세스 후 제거하는 방식입니다. 이 방식은 디른 인덱스 스캔과 달리 Multi Block I/O가 발생합니다. 그래서 결과 집합의 정렬 순서가 보장이 되질 않습니다. 
 

1. 작동 방식

  • 데이터베이스는 병렬화될 수 있는 대규모 I/O 작업에서 인덱스 블록을 읽습니다.
  • 전체 테이블 스캔과 유사하지만 인덱스를 사용하여 항목의 순서를 고려하지 않고 모든 인덱스 항목을 Scan 합니다.

 

2. 예시 쿼리와 실행계획

1
2
3
4
5
6
7
8
9
10
11
12
SELECT 직원명, 생년월일
FROM 직원 a
WHERE 생년월일 = :VAL 
;
 
인덱스 04: 직원명 + 생년월일
 
Execution Plan
-----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=FIRST_ROWS
   1    0   INDEX (FAST FULL SCAN) OF '인덱스_04' (INDEX (UNIQUE))
 
cs