데이터베이스 인덱스란 무엇인가
인덱스는 데이터베이스 테이블의 검색 속도를 향상시키기 위한 데이터 구조이다.
인덱스라 하면 배열의 인덱스 개념이 먼저 떠오를 텐데 데이터베이스에서 인덱스는 비슷하면서 다른 개념이다.
책의 색인처럼 작동하는 별도의 데이터 구조이며, 보통 B-Tree나 해시 테이블 자료구조로 구현된다.
B-Tree 인덱스가 가장 일반적인 인덱스 유형으로 범위 검색에 효율적이고,
해시 인덱스는 정확한 일치 검색에 최적화 되어 있다.
키와 데이터의 물리적 위치 정보를 저장고, 정렬된 상태를 유지하기에 빠른 검색이 가능하다.
예시를 들자면, 배열에서 특정 값을 찾으려면 순차적으로 검색해야 하지만, 데이터베이스의 인덱스가 있다면 사전에서 "ㅎ"으로 시작하는 부분으로 바로 이동하듯이 빠르게 데이터의 위치를 찾을 수 있다.
인덱스는 그럼 어떻게 사용하는가?
기본적으로 사용자가 명시적으로 생성해주어야 한다.
몇 가지 예외적인 상황에서는 자동으로 생성된다.
Primary Key 설정 시
테이블의 기본키로써 자동으로 인덱스가 생성된다.
Unique 제약 조건 설정 시
Unique 제약 조건을 가진 열에 대해 자동으로 인덱스가 생성된다.
Foreign Key 설정 시
일부 데이터베이스에서는 외래키에 대해 자동으로 인덱스를 생성한다.
사용자가 수동으로 인덱스를 설정한다면 다음과 같은 기준이 있을 수 있다.
1.WHERE 절에서 자주 사용되는 열
2.JOIN 연산에 자주 사용되는 열
3.ORDER BY, GROUP BY에 자주 사용되는 열
4.데이터의 고유성이 높은 열
하지만 모든 열에 인덱스를 사용하는 것은 좋지 않다.
인덱스는 별도의 데이터 구조로 저장되기 때문에 추가 저장 공간이 필요하기 때문이다.
또한, INSERT, UPDATE, DELETE 작업 시 인덱스도 함께 업데이트 해야 함으로 성능이 저하 될 수 있다.
그렇기에 실제 서비스에서 쿼리 패턴을 분석하고, 성능 개선이 필요한 부분에 대해 선택적으로 생성하는것이 좋다.
관계형 데이터베이스(RDBMS)에서 스캔 방식은 어떤게 있을까?
MYSQL을 예시로 들면,
Table Full Scan, Index Scan으로 나눌 수 있다.
Index Scan에서 Index Range Scan, Index Unique Scan, Index Full Scan이 있다.
Table Full Scan은 테이블의 모든 데이터를 처음부터 끝까지 검색하는 방식이다.
인덱스를 사용하지 않으며, 작은 테이블이나, 데이터의 대부분을 사용할 때 사용된다.
WHERE조건이 인덱스를 활용할 수 없을 때 사용된다.
Index Scan에서
Index Range Scan는 인덱스 범위검색을 할 때 사용된다 ex_ BETWEEN
인덱스에서 조건을 만족하는 값이 저장된 시작 리프 노드를 찾고(index seek), 필요한 만큼 인덱스를 차례대로 읽는다.(index scan) 인덱스 키와 레코드 주소를 이용해 저장된 페이지를 가져오고 레코드를 읽어온다.
Index Unique Scan은 유니크 인덱스로 단 하나의 값을 찾을 때 사용된다.
Index Full Scan은 인덱스 전체를 순차적으로 검색한다,
인덱스를 ABC 순서로 만들었는데 조건절에 B 혹은 C로 검색하는 경우 사용된다.
인덱스를 생성하는 목정이 아니지만, 그래도 Table Full Scan보다는 빠르다.