추가적인 쓰기 작업과 저장 공간을 활용하여 데이터베이스 테이블의 검색 속도를 향상시키기 위한 자료구조
책에서 원하는 내용을 찾는다고 하면, 책의 모든 페이지를 찾아 보는 것은 오랜 시간이 걸린다. 그래서 책의 맨 앞 또는 맨뒤에 색인을 추가하는데, 데이터베이스의 Index는 책의 색인과 같다.
데이터베이스에서도 테이블의 모든 데이터를 검색하면 시간이 오래 걸리기 때문에 데이터와 데이터의 위치를 포함한 자료구조를 생성하여 빠르게 조회할 수 있도록 돕고 있다. (B+Tree로 구성된 구조에서 Index 파일 건색으로 속도를 향상시키는 기술)
인덱스를 활용하면, 데이터를 조회하는 SELECT 외에도 UPDATE나 DELETE의 성능이 함께 향상된다. 그러한 이유는 해당 연산을 수행하려면 해당 대상을 조회해야만 작업을 할 수 있기 때문이다.
DBMS는 index를 항상 최신의 정렬된 상태로 유지해야 원하는 값을 빠르게 탐색할 수 있다. 그렇기 때문에 인덱스가 적용된 컬럼에 INSERT, UPDATE, DELETE가 수행된다면 각각 다음과 같은 연산을 추가적으로 해주어야 하며 그에 따른 오버헤드가 발생한다.
- INSERT : 새로운 데이터에 대한 인덱스를 추가함
- DELETE : 삭제하는 데이터의 인덱스를 사용하지 않는다는 작업을 진행함
- UPDATE : 기존의 인덱스를 사용하지 않음 처리하고, 갱신된 데이터에 대해 인덱스를 추가함
테이블 생성 시, 3가지 파일이 생성된다.
사용자가 쿼리를 통해 Index를 사용하는 컬럼을 검색하게 되면, 이때 MYI 파일의 내용을 활용한다.
만약 CREATE, DELETE, UPDATE가 빈번한 속성에 인덱스를 걸게 되면 인덱스의 크기가 비대해져서 성능이 오히려 저하되는 역효과가 발생할 수 있다. 그러한 이유 중 하나는 DELETE, UPDATE 연산 때문인데 이 두개는 기존의 인덱스를 삭제하지 않고 '사용하지 않음'처리를 해주므로 SQL문 처리시 비대해진 인덱스에 의해 오히려 성능이 떨어지게 될 것이다.
인덱스를 사용하는 것만큼 생성된 인덱스를 관리해 주는 것도 중요하다. 그러므로 사용되지 않는 인덱스는 바로 제거해 주어야한다.
인덱스 구현에 다양한 자료구조를 사용할 수 있는데, 가장 대표적인 해시테이블과 B+ Tree에 대해 설명
해시 테이블은 (Key, Value)로 데이터를 저장하는 자료구조 중 하나로 빠른 데이터 검색이 필요할 때 유용하다.
해시 테이블은 Key값을 이용해 고유한 index를 생성하여 그 index에 저장된 값을 꺼내오는 구조이다.
해시 테이블의 시간복잡도는 O(1)이며 매우 빠른 검색을 지원한다. 하지만 DB인덱스에서 해시 테이블이 사용되는 경우가 제한적이다. 이유는 해시가 등호(=) 연산에만 특화되었기 때문이다.
해시 함수는 값이 1이라도 달라지면 완전히 다른 해시 값을 생성하는데, 이러한 특성에 의해 부등호 연사(<, >)이 자주 사용되는 데이터베이스 검색을 위해서는 해시 테이블이 적합하지 않다.
예를 들면, "나는"으로 시작하는 모든 데이터를 검색하기 위한 쿼리문은 인덱스의 혜택을 전혀 받지 못한다. 이러한 이유로 B+Tree가 일반적으로 사용된다.
B+Tree는 DB의 인덱스를 위해 자식 노드 2개 이상이 B-Tree를 개선시킨 자료구조이다.
B+Tree는 모든 노드에 데이터(Value)를 저장했던 BTree와 다른 특성을 가지고 있다.
데이터베이스의 인덱스 컬럼은 부등호를 이용한 순차 검색 연산이 자주 발생될 수 있다. 이러한 이유로 BTree의 리프노드들은 LinkedList로 연결하여 순차검색을 용이하게 하는 등 BTree를 인덱스에 맞게 최적화하였다.
(Best Case에 대해 리프노드까지 가지 않아도 탐색할 수 있는 BTree에 비해 무조건 리프노드까지 가야한다는 단점도 있다.)
이러한 이유로 B+Tree는 O(𝑙𝑜𝑔2𝑛)의 시간복잡도를 갖지만 해시 테이블보다 인덱싱에 더욱 적합한 자료구조가 되었다.
위 그림은 InnoDB에서 사용된 B+Tree 구조이다.
InnoDB에서의 B+Tree는 일반적인 구조보다 더욱 복잡하게 구현이 되었다. InnoDB에서는 같은 레벨의 노드들끼리는 LinkedList가 아닌 Double LinkedList로 연결되었으며 자식 노드들은 Single LinkedList로 연결되어있다.
참조 : https://mangkyu.tistory.com/96, https://github.com/gyoogle/tech-interview-for-developer/blob/master/Computer%20Science/Database/%5BDB%5D%20Index.md