---
description: 친절한 SQL 튜닝 2장
---

# 2장 인덱스 기본

### Index Range Scan

B\* 인덱스의 가장 일반적인 탐색 방식이다. 루트에서 리프까지 수직적으로 탐색한 후에 필요한 범위만 스캔한다. 인덱스 선두 컬럼을 가공하지 않은 상태로 조건절에 사용해야 한다.

```sql
CREATE INDEX idx_user_age ON user(age);
SELECT * FROM user WHERE age BETWEEN 25 AND 35;
```

### Index Full Scan

인덱스를 처음부터 끝까지 모두 읽는 방식이다. 대용량 테이블에서 Index Range 스캔을 할 수 없을 때, 차선책으로 선택한다. 수직적 탐색 없이 리프를 처음부터 끝까지 수평으로 탐색한다. 옵티마이저가 index full scan, table full scan 의 효율성을 비교해 선택하는데 주로 조회할 레코드가 적은 경우에 index full scan을 선택한다.

```sql
CREATE INDEX idx_user_age ON user(age);
SELECT age FROM user;
```

### Index Unique Scan

unique 인덱스를 = 조건으로 탐색하는 경우 수직적으로 탐색한다. 데이터를 한 건만 찾고 끝낸다. pk로 조회할 때도 이 스캔 방식을 사용한다.

```sql
CREATE UNIQUE INDEX idx_user_email ON user(email);
SELECT * FROM user WHERE email = 'signature@hyeon.com';
```

### Index Skip Scan

오라클의 새로운 스캔 방식이다. 인덱스 선두 컬럼이 조건절에 없어도 후행 컬럼 조건만으로 선두 컬럼을 반복 스캔하며 인덱스를 재활용하는 방식이다.

```sql
CREATE INDEX idx_user_dept_age ON user(dept, age);
SELECT * FROM user WHERE age = 30; // 후행 컬럼 조건이 있는 경우 (선두는 없어야 함)
```

### Index Fast Full Scan

인덱스 트리 구조를 무시하고 물리적으로 저장된 순서대로 multiblock I/O 방식으로 스캔한다. 전체 인덱스를 정렬 없이, 병렬 가능하게, 빠르게 블록 단위로 읽는 방식이다.

```sql
CREATE INDEX idx_user_age_name ON user(age, name);
SELECT age, name FROM user;
```

### Index Range Scan Descending

Index Range Scan을 역순으로 읽는 방식이다. max 값을 구할 때도 사용한다.

```sql
CREATE INDEX idx_user_age ON user(age);
SELECT * FROM user WHERE age >= 20 ORDER BY age DESC;
```
