인덱스의 의미와 구분, 내부 구조에 대해 정리
인덱스란?
인덱스
- DBMS 인덱스는 SortedList 자료구조 ↔ 데이터 파일은 ArrayList 자료구조
- 저장할 때마다 값을 정렬해야 하므로 저장 과정은 느리나, 이미 정렬되어 있어 조회는 아주 빠름
- 저장 성능을 희생해 읽기 속도를 향상시키는 존재
디스크 읽기 방식
- 전기적 특성을 가진 장치(CPU, 메모리)는 성능이 빠르게 발전했으나, 기계식 장치(디스크)는 제한적이었다.
- 그래서 데이터베이스 관련 성능 튜닝은 디스크 I/O를 어떻게 줄이느냐가 관건인 경우가 많다.
- 취약한 장치에 의해 시스템 전체 성능이 결정되며, 대체로 디스크가 가장 취약하다.
- 쿼리 튜닝은 이런 디스크의 단점을 보완하기 위해 쿼리의 작동 방식을 개선하는 것이다.
SSD 드라이브
- 기계식 디스크 HDD 를 빠른 전자식 장치로 교체하려는 움직임
- D-RAM과 달리 전원 공급과 관계 없이 내용을 영구적으로 보존하는 플래시 메모리를 내장한다.
- D-RAM보다 접근 속도가 떨어지지만 기계식 디스크보다는 월등히 성능이 뛰어나다.
- 랜덤 I/O에 적합하다. 순차 I/O는 HDD도 큰 문제가 없다.
- 랜덤 I/O: 디스크의 원반을 돌려 디스크 헤드가 읽어야할 데이터를 저장된 위치로 이동시킨 다음 읽기를 하는 것
- 순차 I/O: 시작 위치에서부터 쭉 읽어서 데이터를 찾음
- 디스크에서 데이터를 읽고 데이터를 쓰는데 걸리는 시간은 디스크 헤드를 움직여서 읽고 쓸 위치로 옮기는 단계에서 결정된다.
- 3개의 페이지를 디스크에 기록하기 위해 랜덤은 시스템 콜을 3번 요청하고, 순차는 1번 요청한다.
- 순차는 디스크의 헤드를 1번 움직이지만, 랜덤은 3번 움직인 것이다.
- 얼마나 많은 데이터를 한번에 기록하는지보다, 얼마나 자주 디스크에 기록을 요청하는지에 의존적
- 쿼리를 튜닝한다는 것은 얼마나 랜덤 I/O 횟수를 줄이느냐, 즉 필요한 데이터만 읽도록 쿼리하는 것.
인덱스의 구분
- 역할 별 구분
- primary key: 식별자 (null값 불허, 중복 불허)
- secondary key: primary key 제외한 모든 인덱스는 보조 인덱스로 분류한다.
- 데이터 저장 방식 별 구분
- B-Tree 인덱스: 99%가 B-Tree 알고리즘 사용하는 인덱스
- 해시 인덱스: 메모리 기반의 데이터베이스 또는 특수한 용도
- 데이터 중복 여부 별 구분
- Uniqe / Non-Unique index
- optimizer에게는 아주 중요한 정보. equl 조회 시 1건만 리턴되며 더이상 찾지 않아도 된다는 것을 의미
- 클러스터링 인덱스
- 일반적인 인덱스: 레코드를 저장하는 시점에 임의의 빈 공간에 저장
- 클러스터링 인덱스: 인덱스 키 값 순서대로 데이터를 저장해 insert는 느리나, 클러스터링 키 값을 대상으로 범위 검색을 수행하면 랜덤 액세스 없이 레코드를 읽어 아주 빠르게 레인지 스캔 가능.
인덱스 내부
-
MongoDB 엔진과 스토리지 엔진이 레이어로 분리되어 있다. (MySQL 서버처럼)
-
B-tree는 MongoDB의 인덱스를 내부에서 구현하고 있는 데이터 구조다.
- B-Tree는 BST의 self-balancing generalisation(어떻게 해석해야 할지 모르겠음..)이고, self-balancing 트리를 구현하는 방법은 많이 있다.
- balanced BST는 time complecity가 logn.
- B-Tree of order M 예시
- 모든 노드는 최대 m개의 자식을 갖는다. (B-Tree가 항상 두 개의 자식만 갖는 것은 아니다. )
- k개의 자식을 가진 no-leaf 노드는 k-1개의 key를 갖는다.
MongoDB
- MongoDB 컬렉션의 인덱스는 항상 인덱스 필드의 값과 주소 값의 조합인 인덱스 레코드로 구성된다.
- 인덱스 리프 노드의 각 키 값은 테이블의 데이터 레코드를 찾아가기 위한 물리적인 주소 값(MongoDB 내부적으로는 Recordld라고 함)을 가지고 있다.
- 인텍스의 키 값들은 모두 정렬돼 있지만, 테이블의 데이터 레코드는 기본적으로 정렬돼 있지 않고 INSERT 된 순서대로 저장된다.
- B-tree에서 노드는 한개 이상의 value를 가질 수 있고 이를 key라고 부른다.
- 인덱스 키 값은 사용자가 인덱스를 생성할 때 선택한 필드의 값이다.
인덱스 키 엔트리 자료 구조
- MongoDB의 도큐먼트는 key-value로 저장되고 field값도 파일에 같이 저장되어 RDBMS보다 저장되는 데이터의용량이 크다.
- mongoDB는 schema-free 데이터베이스지만 인덱스에는 스키마가 있다.
-
인덱스 키 엔트리에 필드명을 저장할 필요가 없다.
- 키 엔트리 = 레코드 = 인덱스의 각 로우
- 이미 스키마를 가지고 있고, 컴팩트(용량을 작게)하게 유지하는 것이 좋기 때문에
PREVIOUSB-Tree 인덱스