Computer Science/데이터베이스

데이터베이스 인덱스

eunnnn 2023. 3. 25. 12:49

인덱스의 정의

데이터베이스 인덱스란 데이터 베이스의 테이블에 대한 검색 속도를 향상시켜주는 자료구조이다. 테이블의 모든 데이터를 검색하면 시간이 오래 걸리기 때문에 데이터와 데이터의 위치를 포함한 자료구조를 생성하여 빠르게 조회할 수 있도록 하는 것이다.

테이블의 특정 컬럼에 대해 인덱스를 생성하면, 해당 컬럼의 데이터를 정렬한 후 별도의 메모리 공간에 데이터의 물리적 주소와 함께 (key, value)의 쌍의 형태로 저장된다.

장점

  • 테이블 검색 속도, 성능이 향상 되어 이에 따른 전반적인 부하를 줄일 수 있다.
  • 인덱스에 의해 데이터들이 정렬된 형태를 가진다. ( = join, order by가 많은 경우 유리하다)
    기존에는 where문으로 테이블의 전체를 조회하는 Full Table Scan 작업이 필요했는데, 인덱스를 이용하면 정렬된 데이터에서 조건에 맞는 데이터를 바로 찾을 수 있다.

단점

  • 인덱스를 관리하기 위한 추가 작업이 필요하다
  • 추가 저장 공간이 필요하다

 

인덱스의 사용

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

인덱스를 효율적으로 사용하기 위해선 데이터의 range가 넓고 중복이 적을수록, 조회가 많거나 정렬된 상태가 유용한 컬럼에 사용하는 것이 좋다.

  • 데이터의 규모가 큰 테이블
  • WHERE나 ORDER BY, JOIN 등이 자주 사용되는 컬럼
  • 데이터의 중복도가 낮은 컬럼
  • 삽입(INSERT), 수정(UPDATE), 삭제(DELETE) 작업이 자주 발생하지 않는 컬럼

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

DBMS는 index를 항상 최신의 정렬된 상태로 유지해야 원하는 값을 빠르게 탐색할 수 있다. 그렇기 때문에 인덱스가 적용된 컬럼에 INSERT, UPDATE, DELETE가 수행된다면 각각 다음과 같은 연산을 추가적으로 해주어야 한다.

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

이처럼 인덱스의 수정도 추가적으로 필요하기 때문에 데이터의 수정이 잦은 경우 성능이 낮아진다. 또한 DELETE/UPDATE 시에 '사용하지 않음' 처리를 함으로써 인덱스 테이블의 크기는 점차 비대해진다. 또한 인덱스는 전체 데이터의 10 ~ 15% 이상의 데이터를 처리하거나, 데이터의 형식에 따라 오히려 성능이 낮아질 수 있다. 예를 들어 나이나 성별과 같이 값의 range가 적은 컬럼인 경우, 인덱스를 읽고 나서 다시 많은 데이터를 조회해야 하기 때문에 비효율적이다.

 

인덱스의 구현

1. 해시 테이블

해시 테이블은 (Key, Value)로 데이터를 저장하는 자료구조로, Key값을 이용해 고유한 index를 생성하여 그 index에 저장된 값을 꺼내오는 구조이다. (key, value) = (컬럼의 값, 데이터의 위치)로 구현된다.

해시 테이블은 평균적으로 O(1)의 매우 빠른 시간에 원하는 데이터를 탐색할 수 있는 자료구조이기 때문에, 인덱스에 매우 잘 사용 될 것 같지만 실제로는 인덱스에서 잘 사용되지 않는다.

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

 

2. B+ 트리

 

B+Tree는 오직 leaf node에만 데이터를 저장하고 leaf node가 아닌 node에서는 자식 포인터만 저장하는 자료구조다. leaf node끼리는 Linked list로 연결되어있다. leaf node를 제외하고 데이터를 저장하지 않기 때문에 메모리를 더 확보할 수 있고, Full scan을 하는 경우 B+Tree는 leaf node에만 데이터가 저장되어 있고 leaf node끼리 linked list로 연결되어 있기 때문에 선형 시간이 소모된다. 

인덱스 컬럼은 부등호를 이용한 순차 검색 연산이 자주 발생할 수 있다. 따라서 B+Tree의 Linked list를 이용하면 순차 검색을 효율적으로 할 수 있기 때문에 인덱스의 구현에 B+ Tree가 자주 사용된다.

 

 

Table scan vs Clustered Index vs Non Clustered Index

책에 비유하자면,

 

  • 클러스터 인덱스는 페이지를 알기 때문에 바로 그 페이지를 펴는 것 (실제 데이터가 정렬된 사전과 같다)
  • 넌 클러스터 인덱스는 뒤에 목차에서 찾고자 하는 내용의 페이지를 찾고 그 페이지로 이동하는 것. (실제 데이터 탐색에 도움을 주는 별도의 찾아보기 페이지와 같다)
  • 테이블 스캔은 처음부터 한 장씩 넘기면서 내용을 찾는 것

 

Clustered Index

 

 

  • 테이블당 한 개만 생성이 가능합니다.
  • 행 데이터를 인덱스로 지정한 열에 맞춰서 자동 정렬합니다.
  • primary key 설정 시 자동으로 생성되며 컬럼은 데이터 변경 시, 항상 정렬을 유지합니다.
  • clustered index 사용 시 모든 보조 인덱스가 primary key를 포함합니다.
  • primary key의 크기가 커질수록 보조 인덱스의 크기도 커집니다.

 

 

Non Clustered Index

 

  • 테이블 당 여러 개를 생성할 수 있습니다.
  • 맨 뒤의 찾아보기가 있는 일반 책과 같다.
  • B-Tree 의 리프 노드 처럼 노드 자체가 데이터가 아니고, 리프 노드에서는 데이터가 위치하는 주소를 가지고 있는 형태.
  • 테이블의 페이지를 정렬하지 않고 새로운 공간을 할당하므로, 클러스터 인덱스보다 많은 공간을 차지한다.
  • 데이터 행과 분리된 구조를 가진다.

 

출처