인덱스란 추가적인 쓰기 작업과 저장 공간을 활용하여 데이터베이스 테이블의 검색 속도를 향상시키기 위한 자료구조이다. 만약 우리가 책에서 원하는 내용을 찾는다고 하면, 책의 모든 페이지를 찾아 보는것은 오랜 시간이 걸린다. 그렇기 때문에 책의 저자들은 책의 맨 앞 또는 맨 뒤에 색인을 추가하는데, 데이터베이스의 index는 책의 색인과 같다.
데이터베이스에서도 테이블의 모든 데이터를 검색하면 시간이 오래 걸리기 때문에 데이터와 데이터의 위치를 포함한 자료구조를 생성하여 빠르게 조회할 수 있도록 돕고 있다.
규모가 작지 않은 테이블
만약 CREATE, DELETE, UPDATE가 빈번한 속성에 인덱스를 걸게 되면 인덱스의 크기가 비대해져서 성능이 오히려 저하되는 역효과가 발생할 수 있다. 그러한 이유 중 하나는 DELETE와 UPDATE 연산 때문이다. 앞에서 설명한대로, UPDATE와 DELETE는 기존의 인덱스를 삭제하지 않고 '사용하지 않음' 처리를 해준다고 하였다. 만약 어떤 테이블에 UPDATE와 DELETE가 빈번하게 발생된다면 실제 데이터는 10만건이지만 인덱스는 100만 건이 넘어가게 되어, SQL문 처리 시 비대해진 인덱스에 의해 오히려 성능이 떨어지게 될 것이다.
인덱스는 Balanced Tree 를 사용하며 여기에는 대표적으로
RedBlack-Tree와 B-Tree가 있다
인덱스는 이중 B-Tree를 사용하는데 이유를 알기위해 한번 살펴보자
RedBlack-Tree?
RedBlack-Tree는 위 그림처럼 각 노드(node)가 하나의 데이터만 가진 상태로
좌 / 우 SubTree의 밸런스를 유지한다.
B-Tree?
B-Tree는 위처럼 하나의 노드에 여러 데이터가 저장 가능한 트리이며,
Root - Branch - Leaf의 형태를 갖고 있다.
노드 내의 데이터들은 항상 정렬된 상태이며,
해당 데이터들 사이의 범위를 이용하여 자식 노드를 가질 수 있기 때문에
노드 내 데이터의 개수가 N개일 때, 자식 노드의 개수는 (N + 1) 개다.
위 그림들만 봐도 알 수 있듯이,
RedBlack-Tree와 B-Tree의 가장 큰 차이는
'하나의 노드 내의 데이터 개수'이다.
RedBlack-Tree는 하나의 노드 내에 무조건 하나의 데이터만을,
B-Tree는 하나의 노드 내에 여러 데이터를 저장할 수 있다.
이러한 데이터 저장 방식의 차이는 어떤 차이를 일으킬까?
바로 "데이터 탐색 시의 속도 차이"다.
Tree 자료구조에서 데이터를 탐색할 때에는,
가장 위에 있는 root 노드부터 시작하여
찾는 데이터가 나올 때까지 자식 노드로 내려가며 탐색한다.
RedBlack-Tree의 구조를 보면 하나의 노드에 하나의 데이터만 있기 때문에자식 노드로 넘어가는 횟수가 많을 것이고,
그러한 노드와 노드 사이는 "참조 포인터(reference pointer)"로 연결되어 있다.
하지만 B-Tree의 경우,
하나의 노드 내에 정렬된 데이터들이 마치 "배열"의 모습을 띄고 있는데
실제 메모리 상에 배열처럼 차례대로 저장이 되어있다.
⑴ Index Unique Scan
Index Unique Scan은 인덱스를 사용한 검색 방식 중 가장 빠른 방법이다. 이 방식을 사용하기 위해서는 기본 키 또는 Unique
Index가 생성되어 있어야 하며, 인덱스를 구성하고 있는 모든 컬럼이 조건절에서 '='로 비교되어야 한다.
조인되는 Inner Table 과의 조인 조건에도 Unique Index 또는 기본 키 컬림이 모두 조인에 참여했을 때에만 Index
Unique Scan을 할 수 있다.
⑵ Index Range Scan
인덱스를 사용해 인덱스가 생성된 컬럼에 대해 범위 검색을 하는 방법이다.
Unique Index를 사용하지 않거나, 비교연산자를 사용한 대다수의 경우가 이 방식으로 처리되는데, 비교연산자로는 <, <=, >, >=,
between, like 등이 사용될 수 있다.
⑶ Index Skip Scan
Oracle 9i부터 적용이 가능한 방식으로, 결합 인덱스의 선행 컬럼에 대한 조건이 없고, 후행 컬럼에 대한 조건만 있는 경우에 적용.
이 방식은 선행 컬럼 값의 중복을 제거한 값의 종류가 적은 경우에 유리하다.
⑷ Index Full Scan
조건절에서 인덱스 컬럼 중 하나 이상을 사용한 경우 또는 SQL에서 사용한 컬럼들이 모두 하나의 인덱스에 존재할 경우 적용되는 방
식이다.
이 가운데 SQL에서 사용한 컬림들이 모두 하나의 인덱스에 존재할 경우, 인덱스를 구성하는 컬럼 중 최소한 하나의 컬럼은 Not Null
제약 조건을 충족해야 한다. 또, 이 방식을 병렬로 처리하는 것은 불가능하다.(단일 블록 I/O 블록 단위 검색)
⑸ Index Fast Full Scan
Select 절과 조건절에 사용된 모든 컬럼이 인덱스 컬럼으로 구성되어 있어 테이블을 검색하지 않고 인덱스의 블록만을 스캔하여
원하는 데이터를 검색하는 방식이다. Index Full Scan 과 달리 병렬처리가 가능하나, 인덱스 키 데이터의 정렬은 보장되지 않는다.
또, 비트맵 인덱스에 대해서는 이 방식을 적용할 수 없다.