'면접을 위한 CS 전공지식 노트' 책을 보며 공부한 내용입니다.
인덱스의 필요성
인덱스를 통해 빠르게 테이블에 있는 데이터를 찾기 가능하다.
B-트리
인덱스는 보통 B-트리라는 자료 구조로 이루어져 있다. 이는 루트 노드, 리프 노트, 브랜치 노드로 나뉜다.
<=를 기반으로 탐색한다.
- 인덱스가 효율적인 이유
- 효율적인 단계를 거쳐 모든 요소에 접근할 수 있는 균현 잡힌 트리 구조와 트리 깊이의 대수 확장성 때문이다.
- 대수 확장성
- 트리 깊이가 리프 노드 수에 비해 매우 느리게 성장하는 것.
- 기본적으로 인덱스가 한 깊이 증가할 때마다, 최대 인덱스 항목의 수는 4배씩 증가한다.
- 대수 확장성
- 효율적인 단계를 거쳐 모든 요소에 접근할 수 있는 균현 잡힌 트리 구조와 트리 깊이의 대수 확장성 때문이다.
트리 깊이 | 인덱스 항목 수 |
3 | 64 |
4 | 256 |
5 | 1024 |
6 | 4096 |
7 | 16384 |
8 | 65336 |
9 | 262144 |
10 | 1048576 |
실제 인덱스는 이보다 더 효율적이다.
인덱스 만드는 방법
DB마다 다르다.
- MySQL
- 클러스터형 인덱스와 세컨더리 인덱스가 있다.
- 클러스터형 인덱스
- 테이블 당 하나 설정 가능하다
- primary key 옵션으로 기본키를 만들면 클러스터형 인덱스를 생성 가능하다.
- 기본키로 만들지 않고, unique not null 옵션을 붙이면 클러스터형 인덱스로 만들 수 있다.
- 하나의 인덱스만 만들거면 클러스터형 인덱스를 만드는게 더 좋다.
- 세컨더리 인덱스
- create index ... 명령어를 기반으로 인덱스를 만들 때
- 세컨더리 인덱스는 보조 인덱스로 여러개의 필드값을 기반으로 쿼리를 많이 보낼 때 생성해야 한다.
- 예시
- age라는 하나의 필드값을 기반으로 쿼리 -> 클러스터형 인덱스
- age, name, email이라는 여러개의 필드값으로 쿼리 -> 세컨더리 인덱스
- MongoDB
- 도큐먼트를 만들면 자동으로 ObjectID가 형성. 해당 키가 기본 키로 된다.
- 세컨더리키도 부가적으로 설정해서 기본키와 세컨더리 키를 같이 쓰는 복합 인덱스를 설정할 수 있다.
인덱스 최적화 기법
MongoDB 기반으로 설명하지만, 기본적인 골조는 같아서 다른 DB에도 웬만큼 적용 가능.
인덱스는 자주 조회하는 컬럼에 적용하는 것이 좋고, 너무 많은 인덱스는 오히려 성능 저하를 일으킨다.
- 인덱스는 비용이다.
- 인덱스는 두번 탐색을 강요한다.
- 인덱스 리스트, 다음으로 컬렉션 순으로 탐색한다. => 읽기 비용이 들게 된다.
- 컬렉션 수정 시 인덱스도 수정해야 한다.
- B-트리 높이를 균형있게 조절, 데이터 효율적으로 조회할 수 있게 분산 시키는 비용이 들게 된다.
- 쿼리에 있는 필드에 무작정 인덱스를 다 설정하는게 아니다.
- 컬렉션에서 가져와야 하는 양이 많을 수록 인덱스를 사용하는 것은 비효율적이다.
- 인덱스는 모든 쿼리에 필요한 것이 아니고, 특정 쿼리에서만 성능 향상을 얻을 수 있다. 이런 경우에만 인덱스를 적용하는 것이 좋다. 또한, 쿼리의 패턴을 분석하여 해당 쿼리에 적합한 인덱스를 설정하는 것이 좋다.
- 인덱스는 두번 탐색을 강요한다.
- 항상 테스팅하라
- 인덱스 최적화 기법은 서비스 특징에 따라 달라진다. 서비스에서 사용하는 객체의 깊이, 테이블의 양 등이 다르다.
- 그래서 테스팅이 중요하다.
- explain() 함수를 통해 인덱스를 만들고, 쿼리를 보낸 이후에 테스팅하는데 걸리는 시간을 최소화해야 한다.
- MySQL 테스트 코드
- 인덱스 최적화 기법은 서비스 특징에 따라 달라진다. 서비스에서 사용하는 객체의 깊이, 테이블의 양 등이 다르다.
EXPLAIN
SELECT * FROM t1
JOIN t2 ON t1.c1 = t2.c1
- 복합 인덱스는 같음, 정렬, 다중값, 카디널리티 순이다.
- 보통 여러 필드를 기반으로 조회할 때, 복합 인덱스를 생성한다.
- 복합 인덱스를 생성할 때 순서가 있고, 생성 순서에 따라 인덱스 성능이 달라진다.
- 같음을 비교하는 ==이나 equal이라는 쿼리가 있다면 제일 먼저 인덱스로 설정한다.
- 정렬에 쓰는 필드라면 그 다음 인덱스로 설정한다.
- 인덱스는 데이터를 정렬된 순서로 저장하는 구조라서, 정렬에 사용되는 필드에 인덱스를 설정하면 데이터베이스가 정렬을 빠르게 처리할 수 있다.
- 다중 값을 출력해야 하는 필드. 즉, 쿼리 자체가 >이거나 < 등 많은 값을 출력해야하는 쿼리에 쓰는 필드라면 나중에 인덱스를 설정한다.
- 인덱스는 특정 값에 정확히 일치하는 데이터를 찾을 때 매우 유용하다. 그러나 범위 조건을 사용하는 쿼리에서는 한 번에 여러 값을 반환해야 해서, 인덱스의 효율이 상대적으로 낮아질 수 있다.
- 유니크한 값의 정도를 카디널리티라고 한다. 카디널리티가 높은 순으로 인덱스를 설정한다. age와 email을 비교하면 email을 먼저 인덱스 생성해야 한다.
- 고유한 값이 많을 수록, 인덱스가 쿼리 성능을 크게 향상시킬 수 있기 때문이다.
728x90
'CS' 카테고리의 다른 글
4.7 조인의 원리 (2) | 2024.09.30 |
---|---|
4.6 조인의 종류 (1) | 2024.09.28 |
4.4 데이터베이스의 종류 (2) | 2024.09.26 |
4.3 트랜잭션과 무결성 (0) | 2024.09.24 |
4.2 ER Diagram과 정규화 과정 (6) | 2024.09.22 |