[CS] DB에서 인덱스란?

Adler·2024년 1월 16일

CS

목록 보기
10/13
post-thumbnail

인덱스

인덱스란 무엇인가?

데이터베이스에서 인덱스는 데이터 검색을 빠르게 하는 자료구조이다. 예를들어, 책의 인덱스에서 특정 단어를 찾으면, 그 단어가 있는 페이지 번호를 바로 알 수 있다. 이와 유사하게 데이터베이스 인덱스는 특정 데이터가 저장된 위치를 빠르게 찾아준다.

인덱스의 필요성

대규모 데이터를 다루는 DB에서는 데이터 검색 속도가 매우 중요하다. 만일 인덱스가 없다면, 데이터베이스는 요청된 데이터를 찾기 위해 모든 데이터를 순차적으로 검색해야 한다. 실제로 연산을 수행할 때 해당 대상을 조회해야지만 작업을 수행할 수 있다.

UPDATE USER SET NAME = "EUNSU" WHERE NAME = "EUN";

만약 인덱스를 사용하지 않은 컬럼을 조회해야 한다면, 전체를 탐색하는 Full Scan을 수행해야한다.
그래서 인덱스를 활용하면, 데이터를 조회하는 SELECT 외에도 UPDATE, DELETE 성능이 함께 향상된다.

인덱스 관리

DBMS인덱스를 항상 정렬된 상태로 유지해야한다. 이를 통해 원하는 값을 빠르게 탐색할 수 있기 때문이다.
그렇기 때문에 인덱스가 적용된 컬럼에 UPDATE , DELETE 가 수행된다면 각각 다음과 같은 연산을 추가적으로 수행하며 그에 따른 오버헤드가 발생한다.

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

인덱스 장점과 단점

  • 장점
    테이블 조회 속도와 그에 따른 성능 향상
    전반적인 시스템 부하를 줄임
  • 단점
    인덱스를 관리하기 위해 DB 약 10%에 해당하는 저장공간 필요
    인덱스를 관리하기 위한 추가 작업
    * 인덱스를 잘못 사용할 경우 오히려 성능이 저하되는 역효과 발생

인덱스가 성능에 악영향을 주는 경우

데이터베이스에 새로운 데이터가 삽입되거나 기존 데이터가 수정 또는 삭제 될 때 인덱스도 갱신되어야한다.
그 이유는 데이터베이스 무결성과 검색 성능을 유지하기 위함이다.

  • 데이터 무결성 유지
    데이터베이스 내 모든 데이터는 정확하고 일관성 있어야 한다.
    인덱스는 데이터베이스 내 데이터에 대한 참조를 포함하므로, 데이터가 변경될 때 인덱스도 이에 맞춰 갱신되어야 한다.
  • 검색 성능 유지
    * 인덱스 주요 목적은 데이터 검색 효율성 상승이다. 그래서 데이터가 변경될 때 마다 인덱스를 갱신해야만 한다.

이러한 이유로 CREATE,DELETE,UPDATE 가 빈번한 속성에 인덱스를 걸게 되면 인덱스 크기가 커져서 성능이 오히려 저하될 수 있다.

인덱스를 사용하면 좋은 경우

  • 규모가 작지 않은 테이블
  • INSERT, UPDATE, DELETE 가 자주 발생하지 않는 컬럼
  • JOIN 이나 WHERE 또는 ORDER BY에 자주 사용되는 컬럼
  • 데이터 중복도가 낮은 컬럼

인덱스 자료구조

해시 테이블

해시 테이블은 (Key, Value)로 데이터를 저장하는 자료구조 중 하나다.
키 - 값 구조로 인해 빠른 데이터 검색이 필요할 때 유용하다.
해시 테이블은 Key값을 이용해 고유한 Index를 생성하여 그 Index에 저장된 값을 꺼내오는 구조다.

해시 테이블 기반 DB 인덱스는 데이터를 (Key, Value)로 사용하여 컬럼 값으로 생성된 해시를 통해 인덱스를 구현했다. 해시 테이블 시간 복잡도는 O(1)이라 매우 빠른 검색을 지원한다. 하지만 DB 인덱스에서 해시 테이블이 사용되는 경우는 제한적이다. 그러한 이유는 해시가 등호 연산에만 특화되었기 떄문이다. 해시 함수는 값이 1이라도 변경되면 완전히 다른 해시 값을 생성한다. 이러한 특성 때문에 부등호 연산이 자주 사용되는 데이터베이스 검색에는 해시테이블이 적합하지 않다.

해시 테이블이 등호 연산에 특화된 이유
1. 해시 함수 역할

  • 해시 테이블에서는 각 키에 대해 해시 함수가 고유한 해시 값을 생성한다. 이 해시 값은 데이터가 헤시 테이블 내에서 저장되는 정확한 위치를 결정한다.
  1. 직접접근
  • 키를 제공하면, 해시 테이블은 해시 함수를 사용해 해당 키 해시 값을 계산하고, 이를 사용하여 데이터가 저장된 위치를 직접 찾아간다.
  1. 범위 검색 비효율성
  • 특정 범위 값을 지정해주면 해시 테이블 내 모든 요소를 순차적으로 확인해야한다. 이는 비효율적이고 다른 자료구조인 B-트리가 더 효율적이다.

B+ Tree

B+Tree는 DB 인덱스를 위해 자식 노드가 2개 이상인 B-Tree를 개선시킨 자료구조다.
B+Tree는 모든 노드에 데이터를 저장하는 BTree와 다른 특성을 가진다.

  • 리프노드(데이터노드)만 인덱스와 함께 데이터(Value)를 가지고 있고, 나머지 노드(인덱스노드)들은 데이터를 위한 인덱스(Key)만을 갖는다.
  • 리프노드들은 LinkedList로 연결되어 있다.
  • 데이터 노드 크기는 인덱스 노드의 크기와 같지 않아도 된다.

데이터베이스의 인덱스 컬럼은 부등호를 이용한 순차 검색 연산이 자주 발생될 수 있다. 이러한 이유로 BTree의 리프노드들을 LinkedList로 연결하여 순차검색을 용이하게 하는 등 BTree를 인덱스에 맞게 최적화하였다. (물론 Best Case에 대해 리프노드까지 가지 않아도 탐색할 수 있는 BTree에 비해 무조건 리프노드까지 가야한다는 단점도 있다.)

이러한 이유로 비록 B+Tree는 O(𝑙𝑜𝑔2𝑛) 의 시간복잡도를 갖지만 해시테이블보다 인덱싱에 더욱 적합한 자료구조가 되었다.

정리

  • 데이터베이스 인덱스는 데이터 검색 속도를 향상시키고자 사용되는 자료구조다.
  • 인덱스를 통해 대규모 데이터베이스에서 빠른 검색, 업데이트, 삭제 작업을 가능하게 한다.
  • 이는 전반적인 시스템 성능을 개선한다.

질문 리스트

  • 인덱스는 왜 사용하는 것인가요? 인덱스는 데이터베이스에서 데이터 검색 속도를 빠르게 하기 위해 사용됩니다. 특히, 대규모 데이터베이스에서 인덱스 없이 데이터를 순차적으로 검색하는 것은 매우 비효율적이므로, 인덱스를 통해 데이터 검색, 업데이트, 삭제 작업의 성능을 향상시키는 것이 중요합니다.
  • Hash 인덱스와 B-Tree 인덱스의 차이는? 해시 인덱스는 등호 연산에 최적화되어 있으며, 키를 해시 함수를 통해 직접 접근하는 방식으로 작동합니다. 반면, B-트리 인덱스는 범위 검색과 순차적 접근에 유리하며, 데이터를 정렬된 상태로 유지합니다.
  • B-Tree 인덱스와 B+-Tree 인덱스의 차이는? B-트리는 모든 노드에서 데이터를 저장할 수 있지만, B+-트리는 리프 노드에서만 데이터를 저장하고 인덱스 노드는 키만을 갖습니다. B+-트리의 리프 노드는 LinkedList로 연결되어 있어 순차 검색에 더 유리합니다.
  • 인덱스 Scan 방식은? 인덱스 스캔 방식에는 주로 풀 스캔(Full Scan), 레인지 스캔(Range Scan), 유니크 스캔(Unique Scan) 등이 있습니다. 각 방식은 쿼리의 종류와 데이터의 분포에 따라 사용됩니다.
  • 좋은 인덱스를 설계하기 위한 조건은? 좋은 인덱스 설계를 위해서는 데이터 중복도가 낮은 컬럼, 자주 사용되는 컬럼, 데이터 크기, 쿼리의 종류 등을 고려해야 합니다.
  • 인덱스 설계시 NULL값은 고려되야 할까? 네, 인덱스 설계 시 NULL 값은 고려되어야 합니다. NULL 값이 있는 컬럼은 인덱스 효율성에 영향을 미칠 수 있으며, NULL 값을 포함하는 쿼리의 성능에도 영향을 줄 수 있습니다.
profile
지식을 정리하기 위한 블로그입니다.

0개의 댓글