인덱스
: 데이터를 빠르게 찾을 수 있는 하나의 장치
인덱스는 보통 B-트리 자료구조로 이루어져 있다.
루트 노드, 리프 노트, 브랜치 노드로 나뉨
E 탐색하기
: 전체 테이블을 탐색하는 것이 아니라 E가 있을 법한 리프 노드로 들어가서 E를 탐색한다.
자료 구조 없이 이를 행하려고 할 경우 A, B, C, D, E 5번 탐색해야 하지만 노드들로 나누게되면 두 번만에 리프 노드에서 찾을 수 있게 된다.
인덱스가 효율적인 이유와 대수확장성
- 인덱스가 효율적인 이유: 효율적인 단계를 거쳐 모든 요소에 접근할 수 있는 균형 잡힌 트리 구조와 트리 깊이의 대수 확장성 때문
대수확장성
: 대수확장성이란 트리 깊이가 리프 노드 수에 비해 매우 느리게 성장하는 것을 의미한다.
기본적으로 인덱스가 한 깊이씩 증가할 때마다 최대 인덱스 항목의 수는 4배씩 증가한다.트리 깊이가 10일 경우 100만 개의 레코드를 검색할 수 있다는 의미
실제 인덱스는 이보다 훨씬 더 효율적임
MySQL
- 클러스터형 인덱스
- 세컨더리 인덱스
클러스터형 인덱스
: 테이블당 하나를 설정할 수 있다.
primary key 옵션으로 기본키로 만들면 클러스터형 인덱스를 생성할 수 있다.
기본키로 만들지 않고 unique not null 옵션을 붙이면 클러스터형 인덱스로 만들 수 있다.
create index... 명령어를 기반으로 만들면 세컨더리 인덱스를 만들 수 있다.
하나의 인덱스만 생성 -> 클러스터형 인덱스
세컨더리 인덱스
: 보조 인덱스로 여러 개의 필드 값을 기반으로 쿼리를 많이 보낼 때 생성해야 하는 인덱스
MongoDB
: 도큐먼트를 만들면 자동으로 ObjectID가 형성되고 해당 키가 기본키로 설정 된다.
세컨더리키도 부가적으로 설정해서 기본키와 세컨더리키를 같이 쓰는 복합 인덱스 설정 가능
1. 인덱스는 비용이다
: 인덱스는 두 번 탐색하도록 강요한다.
인덱스 리스트, 컬렉션 순으로 탐색하기 때문
컬렉션이 수정되었을 경우 인덱스도 수정되어야 한다.
이때 B-트리의 높이를 균형 있게 조절하는 비용, 데이터를 효율적으로 조회할 수 있도록 분산시키는 비용이 들게 된다.
-> 그렇기 때문에 인덱스를 무작정 다 설정하는게 답은 아님
컬렉션에서 가져와야 하는 양 ↑ -> 인덱스 사용 효율 ↓
2. 항상 테스팅하라
: 서비스에서 사용하는 객체의 깊이, 테이블 양 등이 다르므로 최적화 기법은 서비스 특징에 따라 달라진다. -> 테스팅이 중요
explain()함수를 통해 인덱스를 만들고 쿼리를 보낸 이후에 테스팅을 하며 걸리는 시간을 최소화 해야함..-- MySQL에서 테스팅 수행 하는 코드 EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.c1 = t2.c1
3. 복합 인덱스는 같음, 정렬, 다중 값, 카디널리티 순이다
: 보통 여러 필드를 기반으로 조회 -> 복합 인덱스를 생성
이 인덱스를 생성하는 순서가 있고 순서에 따라 인덱스 성능이 달라짐1. ==, equal 쿼리가 있으면 제일 먼저 인덱스로 설정 2. 정렬에 쓰는 필드 -> 그 다음 인덱스 3. 다중 값 출력(즉, 쿼리 자체가 > 이거나 <)을 해야한다면 나중에 인덱스 설정 4. 카디널리티(유니크한 값의 정도)가 높은 순서를 기반으로 인덱스를 생성해야 함 예를 들어 age, email이 있다면 email이라는 필드에 인덱스를 먼저 생성