GitHub

https://github.com/Choidongjun0830

CS

4.5 인덱스

gogi masidda 2024. 9. 27. 13:14

'면접을 위한 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

 

  • 복합 인덱스는 같음, 정렬, 다중값, 카디널리티 순이다.
    • 보통 여러 필드를 기반으로 조회할 때, 복합 인덱스를 생성한다.
    • 복합 인덱스를 생성할 때 순서가 있고, 생성 순서에 따라 인덱스 성능이 달라진다.
  1. 같음을 비교하는 ==이나 equal이라는 쿼리가 있다면 제일 먼저 인덱스로 설정한다.
  2. 정렬에 쓰는 필드라면 그 다음 인덱스로 설정한다.
    1. 인덱스는 데이터를 정렬된 순서로 저장하는 구조라서, 정렬에 사용되는 필드에 인덱스를 설정하면 데이터베이스가 정렬을 빠르게 처리할 수 있다.
  3. 다중 값을 출력해야 하는 필드. 즉, 쿼리 자체가 >이거나 < 등 많은 값을 출력해야하는 쿼리에 쓰는 필드라면 나중에 인덱스를 설정한다.
    1. 인덱스는 특정 값에 정확히 일치하는 데이터를 찾을 때 매우 유용하다. 그러나 범위 조건을 사용하는 쿼리에서는 한 번에 여러 값을 반환해야 해서, 인덱스의 효율이 상대적으로 낮아질 수 있다. 
  4. 유니크한 값의 정도를 카디널리티라고 한다. 카디널리티가 높은 순으로 인덱스를 설정한다. age와 email을 비교하면 email을 먼저 인덱스 생성해야 한다.
    1. 고유한 값이 많을 수록, 인덱스가 쿼리 성능을 크게 향상시킬 수 있기 때문이다. 
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