Index Range Scan 개요
Index Range Scan은 인덱스를 사용하여 특정 범위 내의 데이터를 검색하는 방식입니다.BETWEEN
, <
, >
, LIKE 'A%'
, IN
등의 연산자를 사용할 때 발생하며, 여러 개의 결과를 반환할 가능성이 있습니다.
Index Range Scan은 SQL튜닝의 꽃으로, 보통 Index Range Scan을 태우기 위해 튜닝을 하는 경우가 많습니다. SQL의 WHERE조건의 첫 번째 조건절을(선두컬럼) 가공한다면 (가공 : A컬럼이면 substr(A,2)라던지.. to_number(A) 등 순수하게 A를 그대로 사용하지 않는 경우) Index Range Scan을 타지 않습니다. (인덱스 구조 공부 필요). 반대로 인덱스의 선두컬럼을 가공하지 않고 첫번째 조건절에 그대로 사용한다면 Index Range Scan을 태울 수 있다는 얘기가 됩니다.
1️⃣ 특징
✔ 범위 검색(연속된 값 검색) 시 사용
✔ 여러 개의 행을 반환할 가능성이 높음
✔ B-Tree 인덱스에서 루트 → 리프 노드까지 탐색 후, 조건에 맞는 데이터까지 순차적으로 읽음
✔ 순차적인 인덱스 검색이므로 성능이 우수함
2️⃣ 사용 조건
- 범위 연산자 (
BETWEEN
,<
,>
,LIKE 'A%'
,IN
)를 사용한 검색 - 인덱스의 일부 키만 사용하는 경우
- 결과가 다수의 행을 반환할 가능성이 있는 경우
3️⃣ 쿼리 예제
(1) 기본적인 Index Range Scan 예제
✅ 범위 검색 (BETWEEN
, <
, >
)
SELECT * FROM EMP WHERE EMP_ID BETWEEN 1000 AND 2000;
🔍 실행 계획 (EXPLAIN PLAN)
INDEX RANGE SCAN (EMP_IDX)
✔ EMP_ID
가 인덱스 컬럼이라면 범위 내 값을 검색할 때 Index Range Scan
발생
✅ 보다 작은 값 검색 (<
)
SELECT * FROM EMP WHERE EMP_ID < 1000;
✔ 1000 이하의 값을 찾기 위해 인덱스에서 처음부터 검색
✅ 보다 큰 값 검색 (>
)
SELECT * FROM EMP WHERE EMP_ID > 1000;
✔ 1000 이후의 값을 찾기 위해 인덱스의 특정 지점에서 끝까지 검색
(2) LIKE 검색에서 Index Range Scan
✅ LIKE 연산자가 접두어 검색(LIKE 'A%'
)일 경우
SELECT * FROM EMP WHERE EMP_NAME LIKE 'A%';
🔍 실행 계획:
INDEX RANGE SCAN (EMP_NAME_IDX)
✔ ‘A%’는 인덱스 정렬 순서를 유지하면서 검색할 수 있어 Index Range Scan
사용 가능
❌ 와일드카드가 앞에 있는 경우 (LIKE '%A'
)는 Index Range Scan 사용 불가
SELECT * FROM EMP WHERE EMP_NAME LIKE '%A';
🔍 실행 계획:
FULL TABLE SCAN
✔ 인덱스를 사용할 수 없어 Full Table Scan 발생
(3) IN
연산자에서 Index Range Scan 발생
✅ IN 연산자 사용
SELECT * FROM EMP WHERE EMP_ID IN (1001, 1002, 1003);
🔍 실행 계획:
INDEX RANGE SCAN (EMP_IDX)
✔ 각각의 EMP_ID
값을 찾아야 하므로 범위 검색처럼 처리됨
(4) Index Range Scan을 강제하는 힌트(Query Hint)
✅ INDEX
힌트 사용
SELECT /*+ INDEX(EMP EMP_IDX) */ *
FROM EMP
WHERE EMP_ID BETWEEN 1000 AND 2000;
🔍 실행 계획:
INDEX RANGE SCAN (EMP_IDX)
✔ 옵티마이저가 다른 실행 계획을 선택하지 않도록 강제 적용
4️⃣ Index Range Scan이 발생하지 않는 경우
❌ 정확한 값(Unique Value)을 조회하는 경우
SELECT * FROM EMP WHERE EMP_ID = 1001;
🔍 실행 계획:
INDEX UNIQUE SCAN (EMP_PK)
✔ 단일 값 검색은 Index Unique Scan
이 발생
❌ LIKE 연산자에서 %
가 앞에 있는 경우
SELECT * FROM EMP WHERE EMP_NAME LIKE '%A';
🔍 실행 계획:
FULL TABLE SCAN
✔ 전체 문자열을 검사해야 하므로 Index Range Scan
이 아닌 Full Table Scan
발생
5️⃣ Index Range Scan vs. 다른 Index Scan과 비교
스캔 유형 | 설명 | 사용 조건 |
---|---|---|
Index Unique Scan | PK, UNIQUE 인덱스에서 단일 값 검색 | WHERE 컬럼 = 값 |
Index Range Scan | 범위 검색 (BETWEEN , < , > ) | WHERE 컬럼 > 값 또는 LIKE 'A%' |
Index Full Scan | 인덱스 전체 검색 | 정렬이 필요하거나 인덱스 자체만 읽을 때 |
Index Fast Full Scan | 멀티 블록 읽기 사용 | 인덱스 전체를 빠르게 읽을 때 |
Index Skip Scan | 복합 인덱스의 일부 키만 사용 | 선행 컬럼 없이 후행 컬럼을 검색할 때 |
6️⃣ 최적화 전략
🔹 범위 검색(BETWEEN
, <
, >
, LIKE 'A%'
)을 효과적으로 사용하면 Index Range Scan을 유도할 수 있음
🔹 불필요한 Full Table Scan을 피하고, 인덱스 검색이 효율적으로 이루어지는지 실행 계획을 확인
🔹 INDEX(TABLE_NAME INDEX_NAME)
힌트를 사용하여 옵티마이저가 Index Range Scan을 사용하도록 유도할 수 있음
📌 정리
✅ Index Range Scan은 범위 검색 (BETWEEN
, <
, >
, LIKE 'A%'
, IN
)을 수행할 때 발생하며, 여러 개의 행을 반환할 가능성이 있음
✅ 정확한 값 검색은 Index Unique Scan
이 발생하지만, 범위 검색이 포함되면 Index Range Scan
이 발생함.
✅ 옵티마이저가 다른 실행 계획을 선택하지 않도록 INDEX
힌트를 사용하여 강제 적용 가능 🚀