데이터베이스 인덱스는 대용량의 DB를 다루다보면 필수적인 개념이기도 하고, 면접 질문으로도 자주 등장한다. 인덱스에 대한 기본적인 개념을 알아보자. (잘못된 내용이 있다면 댓글 남겨주시면 감사하겠습니다!)
데이터베이스 기초 용어
만약 Relation, Domain, 복합 키(Composite key), 기본 키(Primary Key), DBMS 등 데이터베이스 용어에 대해서 익숙하지 않다면 이 링크를 보고 오자.
인덱스란?
책을 보다 보면 맨 뒤쪽에 색인(Index) 페이지가 있어서 그 색인 페이지를 보고 원하는 본문의 내용을 찾아갔던 경험들은 한 번쯤 있을 것이다. 그 색인 페이지는 책의 공간을 일부 차지해서 책의 두께를 두껍게 한다는 단점이 있을 수는 있지만 원하는 본문의 내용을 빠르게 탐색하는데 큰 도움이 되기 때문에 주로 책의 용어들이 중요한 곳에서 많이 사용되고는 한다.
데이터베이스의 인덱스는 이와 매우 유사하다. DBMS에서 실제 데이터 레코드를 더 빠르게 찾아가기 위해서, 데이터 레코드를 참조하는 인덱스를 만들어 데이터의 탐색을 더 빠르게 한다. 책의 색인 페이지를 다시 예시로 들어보자. 색인 페이지는 주로 단어 - 페이지 번호
로 구성이 되는데, DBMS에서는 인덱스 - 데이터 레코드
로 구성이 된다. 색인 페이지에서는 단어를 보고 페이지 번호를 찾아가서 실제 책의 내용을 살펴보는 것처럼, DBMS에서도 컴퓨터가 인덱스를 보고 데이터 레코드를 찾아가 더 빠르게 탐색할 수 있게 되는 것이다.
인덱스의 형태
인덱스의 정의를 알았으니 대략적으로 인덱스가 어떻게 생겼는지 한번 보자.
출처: 데이터베이스 배움터.
Employee
테이블에서 EMPNO
컬럼에 EmpnoIndex
를 걸면 위와 같은 그림이 된다. 인덱스 값이 있고 포인터가 실제 데이터 레코드를 가리키고 있다는 것을 알 수 있다.
인덱스의 특징
- 데이터의 탐색을 빠르게 하는데 쓰인다
- 정렬 되어있다: 책의 색인 페이지는 뒤죽박죽 되어있는 대신 알파벳 순으로 정렬되어 있어서 좀 더 빠르게 찾을 수 있게 된다. 인덱스도 내부적으로 정렬되어 있어서 데이터의 탐색을 더 빠르게 할 수 있게 된다.
- 실제 데이터(레코드)는 정렬이 되어 있을 수도 있고, 안되어 있을수도 있다: 또다시 책으로 예시를 들어보면 영어사전 같은 경우에는 책의 내용이 정렬되어 있지만 소설책 같은 경우엔 책의 내용이 정렬되어 있지 않다. DBMS에서도 실제 데이터 레코드가 정렬이 안되어 있을 수도 있고 되어 있을 수도 있다. 이는 Clustered 인덱스와 Non-clustered 인덱스에서 자세히 알아볼 것이다.
- 몇몇 페이지(공간)를 차지해서 거기에 인덱스가 적혀있다: 책에도 색인페이지가 있는 경우에는 따로 공간을 차지한다. 그것처럼 Index도 존재하기 위해선 공간을 필요로 한다.
- 새로운 데이터(레코드)가 추가, 삭제, 변경되면 이에 상응하는 인덱스를 추가, 삭제, 변경해야 한다: 인덱스를 써서 탐색 속도가 올라간다면 모든 컬럼에 걸면 되지 않을까?라고 생각할 수 있다. 하지만 새로운 데이터 레코드가 추가되었을 때 이에 대응하는 인덱스도 추가되어야하고, 삭제되었을 때도 이에 대응하는 인덱스가 삭제되어야 한다. 이는 데이터베이스의 성능에 많은 부담을 주기 때문에 인덱스를 무분별하게 사용하지 않는 것이 좋다.
인덱스 사용 지침
그렇다면 인덱스는 어느 상황에 인덱스를 쓰는 것이 좋을까. 데이터베이스 배움터라는 책에서는 다음과 같은 지침을 따라 인덱스를 사용할 것을 권장하고 있다.
- tuple이 많이 들어있는 대용량의 relation
- relation에서 대부분의 query가 검색하는 tuple이 2%~4% 인 경우에는 인덱스를 생성하는 것이 좋다.
- 가능하면 한 relation에 세 개 이하의 인덱스를 만드는 것이 좋다. -> CRUD가 일어나면 인덱스를 많이 업데이트 해야하니까!
- 갱신이 빈번하게 이루어지는 attribute/relation은 인덱스를 많이 만드는 것을 피해야한다.
- file의 record들을 충분히 분할할 수 있어야 한다.
- 가능하면 Integer Attribute에 인덱스를 만드는 것이 가장 좋고, 고정 길이 attribute에 인덱스를 만드는 것이 좋다.
- 대량의 데이터를 삽입할 때는 모든 인덱스를 제거하고 데이터 삽입이 끝난 후에 인덱스들을 다시 생성하는 것이 좋다.