DB 인덱스(Index)란?

코딩하는 포로리·2022년 3월 7일
2

DB

목록 보기
3/5
post-thumbnail

📌 1. 인덱스(Index)란?


대부분의 내용과 자료는 해당 포스트에서 가져왔습니다. (클릭)

📎 인덱스란?

인덱스는 데이터베이스 테이블에 대한 검색 성능의 속도를 높여주는 자료구조이다. 특정 컬럼에 인덱스를 생성하면, 해당 컬럼의 데이터들을 정렬하여 별도의 메모리 공간에 데이터의 물리적 주소와 함꼐 저장된다. 또한, 인덱스 생성 시 오름차순으로 정렬하기 때문에 정렬된 주소체계라고 표현할 수 있다.

인덱스를 책에서의 목차라고 생각하면 이해하기 쉽다. 책에서 원하는 내용을 찾을 때 목차나 색인을 이용하면 훨씬 빠르게 찾을 수 있듯이 테이블에서 원하는 데이터를 찾기 위해 인덱스를 이용하면 빠르게 찾을 수 있다. 그러므로 데이터=책의 내용, 인덱스=책의 목차, 물리적 주소=책의 페이지 번호라고 생각하면 된다.



📌 2. 인덱스의 자료구조


인덱스는 여러 자료구조를 이용해서 구현하 수 있는데, 대표적인 자료구조로 해시 테이블과 B+Tree가 있다.

📎 해시 테이블(Hash Table)

해시 테이블은 컬럼의 값물리적 주소(key, value)의 한 쌍으로 저장하는 자료구조이다. 하지만 해시 테이블은 실제로 인덱스에서 잘 사용하지 않는다.

그 이유는, 해시 테이블은 등호(=) 연산에 최적화되어있기 때문이다. 데이터베이스에선 부등호(<,>) 연산이 자주 사용되는데, 해시 테이블 내의 데이터들은 정렬되어 있지 않으므로 특정 기준보다 크거나 작은 값을 빠른 시간 내에 찾을 수가 없다.


📎 B+Tree

B+Tree는 대부분의 DBMS 그리고 오라클에서 특히 중점적으로 사용하고 있는 가장 보편적인 인덱스이다. 구조는 Root Node(기준)/Branch Node(중간)/Leaf Node(말단)으로 구성되며 계층적 구조를 가지고 있다.

  • Node는 데이터가 존재하는 공간이다.
  • Leaf Node만 인덱스(Key)와 함께 데이터(Value)를 가지고 있고, 나머지 Root Node와 Branch Node는 데이터를 위한 인덱스(Key)만을 갖는다.
  • Leaf Node에만 데이터를 저장하고 Leaf Node들끼리 LinkedList로 연결되어 있 선형 시간이 소모되어 시간 효율이 올라간다.
  • Root Node에서 경로를 확인 후, 그에 알맞는 Node들로 이동하여 최종적으로 원하는 데이터가 있는 Leaf Note에 도달한다.

자세한 예시는 해당 포스트에서 확인할 수 있음 (클릭)



📌 3. 인덱스의 장단점


📎 장점: 인덱스를 사용하는 이유

👉 데이터가 정렬되어 있기 때문에 테이블에서 검색과 정렬 속도를 향상시킨다.

  • 조건 검색 Where절의 효율성: 보통 Where절의 사용할 때 특정 조건에 맞는 데이터를 찾기 위해 데이터를 처음부터 끝까지 다 비교해야 하는데, 인덱스를 통해 데이터가 정렬되어 있으면 빠르게 찾아낼 수 있다.
  • 정렬 Order by 정의 효율성: 인덱스를 사용하면 Order by에 의한 Sort과정을 피할 수 있다. 본래 Order by는 괴장히 부하가 많이 걸리는 작업이기 때문에 인덱스를 통해 이미 정렬되어 있으면 부하가 걸리지 않을 수 있다.
  • MIN, MAX의 효율적인 처리가 가능: 이것또한 인덱스를 통해 데이터가 정렬되어 있기 때문에 처음부터 끝까지 뒤져서 찾는 것이 아닌 인덱스로 정렬된 데이터에서 MIN, MAX를 효율적으로 추출할 수 있다.

👉 인덱스를 사용하면 테이블 행의 고유성을 강화시킬 수 있다.

👉 시스템의 전반적인 부하를 줄일 수 있다.


📎 단점: 인덱스 사용시 주의할 점

👉 인덱스의 가장 큰 문제점은 정렬된 상태를 계속 유지시켜야 한다는 점이다.

인덱스가 적용된 컬럼에 정렬을 변경시키는 INSERT, UPDATE, DELETE 명령어가 수행된다면 계속 정렬을 해주어해서 그에 따른 부하가 발생한다. 이런 부하를 최소화하기 위해 인덱스는 데이거 삭제라는 개념에서 인덱스를 사용하지 않는다 라는 작업으로 이를 대신한다.

  • INSERT: 새로운 데이터에 대한 인덱스를 추가
  • DELETE: 삭제하는 데이터의 인덱스를 사용하지 않는다는 작업 진행
  • UPDATE: 기존의 인덱스를 사용하지 않음 처리하고, 갱신된 데이터에 대해 인덱스 추가

👉 무조건 인덱스 스캔이 좋은 것은 아니다

검색을 위주로 하는 테이블에 인덱스를 생성하는 것이 좋지만 무조건 인덱스가 검색에 좋은 것은 아니다. 예를 들어, 1개의 데이터가 있는 테이블과 100만개의 데이터가 들어 있는 테이블이 있다고 하자. 100만 개의 데이터가 들어있는 테이블이라면 풀 스캔보다는 인덱스 스캔이 유리하겠지만, 1개의 데이터가 들어있는 테이블은 익덱스 스캔보다 풀 스캔이 더 빠르다.

👉 속도 향상을 위해 인덱스를 많이 만드는 것이 좋지 않다.

인덱스를 관리하기 위해서는 데이터베이스의 약 10%에 해당하는 저장공간이 추가로 필요하다. 때문에 너무 많이 인덱스를 생성하면 하나의 쿼리문을 빠르게 만들 수 있지만 대신에 전체적인 데이터베이스의 성능 부하를 추래한다. 때문에 무조건적인 인덱스 생성보다 SQL문을 효율적으로 짜고, 인덱스 생성은 마지막 수단으로 사용해야한다.



📖 참고

0개의 댓글