많은 사람들이 DB의 인덱스를 항상 책 맨 끝에 있는 찾아보기(색인)으로 설명한다. 책의 마지막에 있는 찾아보기가 인덱스라면, 책의 내용은 데이터 파일에 해당한다고 할 수 있다. 책의 찾아보기를 통해 알아낼 수 있는 페이지번호는 데이터 파일에 저장된 레코드 주소에 비유될 것이다.
사실 책의 찾아보기와 인덱스의 공통점 가운데 가장 중요한것은, 정렬이다. DBMS의 인덱스도 찾아보기와 마찬가지로 컬럼의 값을 주어진 순서로 미리 정렬해 보관한다.
자료구조로 설명하자면, SortedList 가 인덱스이고, ArrayList 가 데이터 파일이다. 데이터 파일은 값이 저장되는 순서 그대로 유지하고, 인덱스는 미리 지정된 순서로 값을 항상 정렬해둔다.
예상되는 것 처럼 SortedList 는 데이터가 저장될 때마다 항상 값을 정렬해야 하므로 저장하는 과정이 복잡하고 느리다. 하지만 조회성능에 있어서는 매우 빠르다. DBMS도, 인덱스가 많은 테이블은 INSERT , UPDATE , DELETE 문장의 처리가 느리다. 하지만 SELECT 는 매우 빠르다.
결론부터 말하자면, 인덱스는 데이터의 저장 성능을 희생한 대신 데이터의 읽기 속도를 높이는 기능이다.
따라서 테이블의 인덱스를 하나 더 추가할지 말지는 데이터의 저장속도를 어디까지 희생할 수 있는지, 읽기 속도를 얼마나 더 빠르게 만들어야 하느냐에 따라 결정해야 한다. WHERE 에 사용되는 컬럼이라고 전부 인덱스로 생성하면 데이터 저장성능이 떨어져 오히려 역효과를 불러올 수 있다.
이 책에서는 인덱스를 알고리즘과 중복 값의 허용 여부 등에 따라 구분할 것이다.
역할별로 구분한다면 프라이머리키(Primary Key)와 보조키(Secondary Key)로 구분할 수 있다. 사실 보조키는 PK가 아닌 모든 인덱스를 의미한다. 유니크 인덱스는 PK를 대신해서 사용할 수 있으므로 대체 키라고도 하지만, 보조키로 분류하기도 한다.
이하에서는 인덱스를 Key와 같은 의미로 사용할 것이다.
인덱스를 알고리즘별로 구분하면 대표적으로는 B-Tree인덱스와 Hash인덱스가 있다. 최근에는 Fractal-Tree인덱스나 로그 기반의 Merge-Tree인덱스와 같은 알고리즘을 사용하는 DBMS도 있다.
데이터 중복 허용 여부로 분류하면, 유니크 인덱스와 Non-Unique로 구분할 수 있다. 옵티마이저에게는 데이터가 유니크한지 아닌지가 상당히 중요하다. 유니크 인덱스에 대해 동등조건(=)으로 검색하면 1건만 찾으면 끝이라는걸 옵티마이저에게 알리는 것과 같기 때문.
인덱스를 기능별로 분류하면, 전문 검색(full-text)인덱스나 공간 검색용 인덱스를 예로 들 수 있다. 이밖에도 많지만 MySQL을 사용할때는 이 두 가지만으로도 충분하다.