@markdown
# 인덱스 기본 원리
____
<br/>
## 인덱스 구조
### 인덱스 기본 구조
- 인덱스는 데이터를 빨리 찾도록 돕는다
- 루트 : 데이터 값 범위를 나타내는 키값
- 브랜치 블록 : 키 값에 해당하는 블록을 찾는 데 필요한 주소 정보
- 리프 블록 : 데이터가저장되 있는 블록
![](http://wiki.gurubee.net/download/attachments/26745270/pict_00000.jpg)
<br/>
### 인덱스 탐색
____
- 수직적 탐색, 수평적 탐색
![](http://wiki.gurubee.net/download/attachments/26745270/pict.jpg)
## 다양한 인덱스 스캔 방식
____
### Index Range Scan
- 인덱스 루트 블록에서 리프 블록까지 수직적으로 탐색한 후에 리프 블록을 필요한 범위만 스캔하는 방식
- 인덱스를 스캔하는 범위를 줄이느냐, 테이블 액세스를 줄이냐 관건
- Index Range Scan이 가능하게 하기 위해 인덱스를 구성하는 선두 컬럼이 조건절에 사용되어야 한다.
- Index Range Scan 과정을 거쳐 생성된 결과집합은 인덱스 컬럼 순으로 정렬된 상태이므로 sort order by, min/max 값을 빠르게 추출 할 수 있다.
![range scan](https://user-images.githubusercontent.com/12658717/40886652-1cedf776-6777-11e8-983d-46fec9c6e29a.png)
### Index Full Scan
- 인덱스 리프 블록을 처음부터 끝까지 수평적으로 탐색하는 방식(최적의 인덱스가 없을 때 차선)
![full scan](https://user-images.githubusercontent.com/12658717/40886665-4c151516-6777-11e8-934b-5adfc4d8359b.png)
### Index Unique Scan
- 수직적 탐색만으로 데이터를 찾는 스캔 방식
- `=` 조건으로 탐색하는 경우 작동
![Unique Scan](https://user-images.githubusercontent.com/12658717/40886681-8216272c-6777-11e8-9bfe-80870ea68162.png)
### Index Skip Scan
- 선두 칼럼이 조건절에 빠져도 활용할 수 있는 스캔 방식
- 루트 or 브랜치 블록에서 읽은 컬럼 값 정보를 이용해 조건에 부합하는 레코드를 포함할 가능성 있는 하위 블록만 골라 액세스 하는 방식
![Skip Scan](https://user-images.githubusercontent.com/12658717/40886763-e22d3c80-6778-11e8-95a4-30ff7a66775d.png)
### Index Fast Full Scan
- Index Full Scan 보다 빠른 스캔방식
- 인덱스 트리 구조를 무시하고 인덱스 세그먼트 전체를 Multiblock Read 방식으로 스캔함
### Index Range Scan Descending
- Index Range Scan과 기본적으로 동일함
- 인덱스 뒤쪽에서부터 앞쪽으로 스캔하기 때문에 내림차순으로 정렬된 결과집합을 얻는다.
![Descending Range Scan](https://user-images.githubusercontent.com/12658717/40886785-456a7038-6779-11e8-868c-991e368bf5bd.png)
## 인덱스 종류
### B-Tree 인덱스
- 모든 DBMS가 B-Tree 인덱스를 기본적으로 제공
- B-Tree 인덱스 구조에서 나타날 수 있는 Index Fragmentation이 있다.
#### 1) Unbalanced Index
- delete 작업 때문에 인덱스가 불균형 상태에 놓이는데 B-Tree 구조에서는 발생하지 않음
#### 2) Index Skew
- 인덱스 엔트리가 왼쪽 또는 오른쪽으로 치우치는 현상
- Oracle에서는 커밋해도 인덱스 구조상에 그대로 남기 때문에 상위 브랜치에서 해당 리프 블록을 가리키는 엔트리가 그대로 남아 있어 인덱스 정렬 순서상 그곳에 입력될 새로운 값이 들어오면 언제든 재사용될 수 있다.
#### 3) Index Sparse
- 인덱스 블록 전반에 걸쳐 밀도가 떨어지는 현상
- 데이터를 지워도 인덱스의 블록 수는 그대로이다.(인덱스 효율 저하)
#### 4) 인덱스 재생성
- Index Fragmentation 때문에 인덱스 크기가 계속 증가하고 스캔 효율이 나빠지면 인덱스를 재생성 하여 빈 공간을 제거하는 것이 유용함
- 재생성 시점은 자주 사용되는 인덱스 스캔 효율을 올릴 때 사용(NL Join에서 반복 액세스 되는 인덱스 높이가 증가했을 때)
### Bitmap Index
![bitmap index](http://wiki.gurubee.net/download/attachments/26745270/pict_00002.jpg)
- Null을 저장하는 구조
- 부정형 조건 사용시에도 Scan이 가능
### 함수기반 인덱스(Function Based Index)
- 컬럼 값에 가공 함수를 적용하여 index 생성
- 컬럼을 가공한 값을 이용해 데이터 검색 해야하는 요건이 있을 때
- DML로 인한 인덱스 갱신 시 함수까지 적용하여 갱신하므로 추가적인 부하 고려 필요함
- 함수를 사용하기 때문에 다소 부하가 있을 수 있음
### Reverse Key Index
![Reverse Index](http://wiki.gurubee.net/download/attachments/26745270/pict_00003.jpg)
- 입력된 키 값을 거꾸로 변환하여 저장하는 인덱스
- 입력되는 값을 거꾸로 변환하여 저장하면, 데이터가 고르게 분포하여 한쪽으로만 집중되는 트랜잭션을 리프 블록 전체에 고르게 분산시키는 효과가 있다.
### Cluster Index(Oracle)
![Cluster Index](http://wiki.gurubee.net/download/attachments/26745270/cluster%20index.JPG)
- Cluster Key 값이 같은 레코드가 한 블록에 모이도록 저장하는 구조
- 한 블록에 모두 담을 수 없을 때에는 여러 블록을 Cluster Chain으로 연결
- Cluster Index : Cluster 테이블을 탐색하기 위한 인덱스
### 클러스터형 인덱스 / IOT
- B-Tree와 같은 형태
- 별도 테이블을 생성하지 않고 모든 행 데이터를 인덱스 리프 페이지에 저장한다는 점
- 인덱스 리프 페이지가 곧 데이터 페이지
- 활용 : 넓은 범위를 주로 검색하는 테이블, 크기가 작고 NL Join으로 반복 룩업하는 테이블, 컬럼 수가 적고 로우 수가 많은 테이블, 데이터가 입력과 조회 패턴이 서로 다른 테이블
> SQL 전문가 가이드 : 과목3. SQL 고급 활용 및 튜닝, 4장 인덱스와 조인 - 제1절 인덱스 기본 원리(p.598 ~ p.620)
> 사진 출처 : 구루비넷
'SQLP 자격증' 카테고리의 다른 글
SQLP - 쿼리변환(2) (0) | 2018.05.28 |
---|---|
SQLP - 쿼리변환(1) (0) | 2018.05.22 |
SQLP - 옵티마이저 (0) | 2018.05.08 |
SQLP - 동시성 제어 (0) | 2018.05.07 |
SQLP - 트랜잭션(Transaction) (0) | 2018.05.02 |