Database Index
색인(Index)
내가 원하는 부분에 쉽고 빠르게 찾아서 전달해주는 역할
왜 DB에서 Index를 사용해야할까?
테이블에서 어떤 값을 조회할 때, 테이블에 있는 데이터를 모두 조회한 후
최종적으로 해당값이 포함된 모든 값들을 반환하는 로직으로 작동한다.
인간이 직관적으로 결과를 찾아낼 때에는 찾는 값이 마지막으로 들어있는 위치를 알고
아래 데이터들을 무시할 수 있다.
하지만 데이터베이스 조회 구문은 찾는 값의 마지막 위치가 어디인지 모르기떄문에
데이터 전체를 탐색함으로써 결과를 반환해준다.
만약 데이터가 수십만개가 들어있을때 조회기능이 자주 실행되는 서비스가 있다면
계속해서 데이터베이스를 처음부터 끝까지 조회해서 값을 반환하니까 트래픽에따라 성능이 저하된다.
그래서 데이터베이스에서 이러한 문제점을 방지하고자 Index를 활용해
자주 조회되는 Column에 대한 Index Table을 따로 만들어
select문이 들어왔을 때 Index 테이블에 있는 값들로 결과값을 조회해온다.
따라서 Index를 잘 사용하면 검색 연산을 실행했을 때 성능을 드라마틱하게 올릴 수 있다.
Index 동작은 “어떻게” 동작하나?
테이블 생성 시 특정 칼럼에 대한 인덱스를 주면 해당 칼럼에 대한 인덱스 테이블이 생성된다.
그리고 나중에 해당 테이블의 특정 컬럼에 대한 WHERE문이 포함된 쿼리가 나갈 때
해당 컬럼의 인덱스 테이블에 저장된 key-value 값을 참조해서 결과값을 반환해온다.
동작순서
- Index Table에서 Where에 포함된 값을 찾음.
- 해당 값의 table_id (PK)를 가져옴
- 가져온 table_id (PK) 값으로 원본 테이블에서 값을 조회해옴
B-Tree 인덱스 알고리즘
DBMS는 Index를 다양한 알고리즘으로 관리하는데 일반적으로는 B-Tree 알고리즘을 사용한다.
B-Tree 구성
- 리프 노드 : 실제 데이터가 저장되는 노드
- 논리 노드 : 리프 노드까지의 경로 역할을 하는 노드
- 루트 노드 : 경로의 출발점 노드
B-Tree는 리프 노드에 이르기까지 자식 노드에 대한 포인터가 저장되어있어
탐색할 때 루트 노드에서 어떤 리프 노드에 이르는 한 개의 경로만 검색하면 되기 때문에
검색에 있어 매우 효율적인 알고리즘이다.
Index 종류
인덱스 기존 DB 테이블과 달리 데이터 중복성을 가질 수 있다.
그래서 다양한 종류의 인덱스 형태가 존재하는데, 인덱스 종류는 사용 목적에 따라 적절히 사용해야한다.
키에 따른 인덱스 분류
-
기본 인덱스(Primary Index) : 기본키를 포함하는 인덱스(키의 순서가 레코드의 순서를 결정)
-
보조 인덱스(Secondary Index) : 기본 인덱스 이외의 인덱스(키의 순서가 레코드의 순서를 의미하지는 않음)
파일 조직에 따른 인덱스
- 집중 인덱스(Clustered Index) : 데이터 레코드의 물리적 순서가 그 파일에 대한 인덱스 엔트리 순서와 동일하게(유사하게) 유지되도록 구성된 인덱스
- 비집중 인덱스(Unclustered Index) : 집중 형태가 아닌 인덱스
데이터 범위에 따른 인덱스 분류
- 밀집 인덱스(Dense Index) : 데이터 레코드 각각에 대해 하나의 인덱스 엔트리가 만들어진 인덱스
- 희소 인덱스(Sparse Index) : 레코드 그룹 또는 데이터 블록에 대해 하나의 엔트리가 만들어지는 인덱스
언제 인덱스를 사용할까?
인덱스의 특징
-
인덱스 테이블
인덱스는 하나의 테이블을 생성해 값을 저장해놓고 사용한다.
그래서 다른 테이블에 의존적인 새로운 테이블이 하나 생성된다는 점에서
무분별한 인덱스 생성은 성능 저하를 초래할 수 있다.
-
정렬
인덱스 테이블은 “이진트리 검색"을 사용하기 때문에 기본적으로 정렬되어 있다.
그래서 만약 인덱스 테이블이 참조하는 테이블에서 “삽입”, “삭제”, “수정"이 자주 일어나면
인덱스 테이블에서는 데이터를 정렬하면서 삽입, 삭제, 수정이 이루어지기 떄문에 성능이 저하될 수 있다.
-
결과적으로 인덱스는 “검색"에 최적화된 기능이므로 삽입, 삭제, 수정이 자주 일어나는 비지니스 로직 혹은 테이블 사용 용도에 따라 인덱스 사용 여부를 신중하게 고민해봐야 한다.
인덱스 사용 예시
https://itholic.github.io/database-index/ 에 아주 잘 설명되어있다.
참고: