본문 바로가기

DB

데이터베이스 인덱스

방대한 양의 데이터중에서 원하는 데이터를 찾으려면 하나씩 찾아봐야 해서 굉장히 많은 시간이 걸린다. 이러한 상황 때문에 검색의 효율을 늘리기 위해서 인덱스라는 자료구조를 사용한다. 책을 보면 앞에 목차를 통해 효율적으로 원하는 카테고리에 들어갈 수 있는데 다음 그림과 같이 index 또한 이와 비슷하다고 볼 수 있다. 

인덱스의 특징

위와 같다면 인덱스를 사용하는것이 항상 옳다고 느껴질수도 있다. 하지만 다음과 같은 인덱스의 특징을 이해하고 사용한다면 더 좋은 성능의 데이터 베이스를 사용할 수 있을것이다.

 

데이터 베이스에 인덱스를 만들다 보니 필연적으로 인덱스가 차지하는 공간이 생기게 된다. 이는 약 DB의 10%에 해당되는 공간이다. 그럼에도 불구하고 인덱스를 사용하면 쿼리의 부하가 줄어들어서 결국 시스템의 전체의 성능이 향상될 수 있기에 인덱스를 사용한다.

하지만 예를들어 성별이라는 열을 인덱스로 생성한다고 생각해보자. 성별은 남자, 여자밖에 없기 때문에 굉장히 많은 데이터가 중복될 것이고 인덱스를 사용한다 하더라도 조회를 하는데 오래 걸릴것이다. 이처럼 데이터의 중복이 많이 일어나는 열에 대해서는 인덱스를 생성하지 않는게 더 효율적이다.

또한 update, delete, insert문을 사용할때 성능이 많이 떨어지는데 이는 인덱스의 자료구조를 보면서 설명하겠다.

 

위와같은 인덱스의 특징을 알면 우리는 어떠한 컬럼을 인덱스로 사용하면 괜찮을지 알 수 있다. 다음과 같은 상황에서 사용하면 괜찮은데 그 밖에도 상황에 따라 인덱스의 특징을 이해하며 사용하면 될것이다.

  • 1. 조건절에 자주 등장하는 컬럼
  •  항상 = 으로 비교되는 컬럼
  • 중복되는 데이터가 최소한인 컬럼 (분포도가 좋은) 컬럼
  • ORDER BY 절에서 자주 사용되는 컬럼
  • 조인 조건으로 자주 사용되는 컬럼
  • 규모가 작지 않은 테이블

인덱스의 자료구조

위에서 insert, delete, update 작업이 일어날때 성능이 나빠진다고 했다. 인덱스의 자료구조를 보면 그 이유를 알 수 있다.

B-Tree(Balanced Tree, 균형트리)

B-Tree는 '자료 구조'에 나오는 범용적으로 사용되는 데이터 구조다. 이 구조는 주로 인덱스를 표현할 때와 그 외에도 많이 사용된다. 이름에서도 알 수 있듯이 B-Tree는 균형이 잡힌 트리다.

위와 같이 B-Tree의 구조가 이루어져 있다고 생각해보자. 루트 노드와 리프 노드가 서로 연결되어 있기에 25란 데이터를 조회한다고 가정하면 10->20->23->27->25 총 5번의 과정만 거치면 조회할 수 있다. 이러한 구조 때문에 검색을 할때에는 굉장히 효율적이다. 그렇다면 중간에 데이터가 삽입되거나 삭제되거나 변경될때는 어떻게 될까? 운이 좋을 경우에는 분할이 일어나지 않지만 운이 안좋을 경우 분할이 일어난다. 위의 경우에서는 13이라는 데이터를 넣다고 가정해보자.

그렇다면 다음과 같은 일이 생길 것이다. 

 

이러한 과정이 생긴다면 성능이 상당히 떨어질 것이다. 그래서 update, delete, insert 쿼리를 자주 사용하는 컬럼에 index를 생성하지 말라고 하는것이다. 또한 인덱스는 삭제되지가 않는다. 예를들어 위에서 18이라는 데이터를 삭제한다고 했을때 실제로는 삭제되지 않고 사용안함 표시가 된다. update를 할때도 마찬가지로 18을 19로 바꾼다면 18은 사용하지 않는다고 표시되며 19라는 데이터가 새롭게 삽입이 된다. 이러한 과정 때문에 update, delete, insert 쿼리를 자주 사용하는 컬럼에 대해서는 인덱스를 사용하지 않는것이 더 성능에 좋을것이다.

 

인덱스의 종류

인덱스에는 클러스터형 인덱스와 보조형 인덱스가 있다. 

클러스터형 인덱스

  • 클러스터형 인덱스는 테이블의 물리적인 저장 순서를 결정한다. 따라서 테이블당 하나의 클러스터형 인덱스만 가질 수 있다.
  • 테이블당 한개만 생성 가능
  •  클러스터형 인덱스에서의 데이터 삽입, 삭제, 수정 연산은 데이터 페이지의 재구성을 초래할 수 있어서 성능에 영향을 줄 수 있다.

보조형 인덱스

  • 책과 같이 <찾아보기>가 별도로 있고, <찾아보기>를 통해 찾은 후에 그 옆에 표시된 페이지로 가야 실제 내용이 있는 형식
  • 테이블에 여러개 생성 가능
  • 비클러스터형(보조형) 인덱스는 데이터의 물리적인 저장 순서에 영향을 주지 않는다. 그러나 인덱스를 구성하는 키는 정렬되어 저장된다.
  • 따라서 삽입, 삭제, 수정의 연산이 발생할 때, 비클러스터형 인덱스 또한 페이지 분할이나 합병을 경험할 수 있다.
  • 데이터를 조회할 때, 보통 인덱스 페이지를 먼저 조회하고, 해당 페이지가 가리키는 데이터 페이지를 조회하는 과정을 거치게 된다. 이를 "인덱스 탐색 후 데이터 탐색"이라고 한다. 이는 클러스터형 인덱스에 비해 조회 성능이 약간 떨어질 수 있지만, 적절한 인덱스 설계와 쿼리 최적화를 통해 성능을 개선할 수 있다.

구조의 차이

 

 

위의 특징을 통해 둘의 구조가 차이날 수 있다. 위에서 설명한 바와 같이 클러스터형 인덱스는 자동으로 정렬되기 때문에 데이터의 삽입, 삭제, 수정의 연산이 수행될 경우 페이지의 분할이 일어나 성능이 더 저조하지만 검색할때는 빠르다는 특징이 있다. 또한 인덱스 페이지 자체가 찾는 데이터이기 때문에 따로 데이터 페이지가 존재하지 않아도 된다.

 

하지만 보조형 인덱스인 경우 자동으로 정렬되지 않아 삽입, 삭제, 수정의 연산이 일어날 때 물리 저장소의 페이지 분할이 일어나지 않기에 이러한 연산에 대해서는 덜 느리지만 조회할 때에는 데이터 페이지가 따로 존재하여 인덱스 페이지에는 데이터 페이지의 주솟값이 들어있기에 인덱스 페이지 조회 -> 데이터 페이지의 조회의 두번의 과정을 거치기에 더 느리다.


위와 같이 인덱스에 대해서 알아봤다.  그렇다면 인덱스를 사용하여 성능이 높아졌다는것을 어떻게 알 수 있을까?

우리는 쿼리 실행계회을 통해 쿼리 성능을 알 수 있다. 인덱스를 적절히 잘 사용했다면 쿼리성능이 높아졌다는 것을 확인할 수 있다.

'DB' 카테고리의 다른 글

MySQL 설치 및 DB 구축과정 미리 실습하기: DBMS 개요와 MySQL 소개  (0) 2023.08.01
정규화  (0) 2023.01.09
데이터 베이스의 시작  (0) 2023.01.06
Requires_new  (0) 2022.12.18
트랜잭션  (2) 2022.12.12