본문 바로가기
Computer Science/데이터베이스

인덱스(Index)

by Libi 2021. 7. 10.
반응형

인덱스는 데이터 레코드를 빠르게 접근하기 위해 <키 값, 포인터> 쌍으로 구성되는 데이터 구조이다.

간단히 말해서 책의 색인(목차)이라고 할 수 있다. 책의 색인을 통해 원하는 페이지로 한 번에 이동할 수 있다. 이처럼 데이터베이스에서의 인덱스는 데이터베이스의 데이터를 빠르게 조회할 수 있는 자료구조이다.

인덱스에 대해 공부하기 전에 인덱스가 왜 필요한지에 대해서 먼저 알아보자.

테이블 A에 수 만개의 데이터가 있다고 하자. SELECT 문을 통해 원하는 데이터를 조회한다고 하면 어떻게 될까? 기준이 없기 때문에 테이블에 있는 모든 데이터를 순차적으로 읽는 FULL TABLE SCAN을 통해 원하는 데이터를 찾아야 한다. 이는 굉장히 비효율적인 방법이다.

인덱스를 사용한다면 효율적으로 조회할 수 있다. 테이블 A의 데이터들을 색인화하여 별도의 저장 공간을 만든 후 원하는 데이터를 조회할 때 저장 공간에서 키 값으로 주소를 찾아 바로 조회하면 된다. 이처럼 데이터 조회를 빠르게 하기 위해서 인덱스가 필요하다.

인덱스는 WHERE 절을 사용한 SELECT 문에만 효과가 있다. WHERE 절을 사용하지 않고 인덱스가 걸린 컬럼을 조회하는 것은 성능에 아무런 영향이 없다.

그렇다면 인덱스는 어떻게 구현할까? 인덱스를 구현하기 위해 사용되는 대표적인 자료구조는 해시 테이블B+Tree이다. 해시 테이블과 B+Tree는 각각 O(1), O(log N)의 시간 복잡도를 가진다. 해시 테이블이 성능이 훨씬 좋아 보이지만 일반적으로 B+Tree 자료구조를 사용한다.

그 이유는 간단하다. 해시 테이블은 동등 연산(=)에만 사용 가능하기 때문이다. 우리는 데이터를 조회하기 위해 SELECT 문을 사용할 때 동등 연산뿐만 아니라 부등호 연산(<, >)도 사용할 수 있다. 따라서 해시 테이블은 인덱스 자료구조로 적합하지 않다.

인덱스의 장점은 다음과 같다.

  • 키 값을 기초로 하여 테이블에서 검색과 정렬 속도를 향상시킴
  • 질의나 보고서에서 그룹화 작업의 속도를 향상시킴
  • Index를 사용하면 테이블행의 고유성을 강화시킬 수 있음
  • 테이블의 기본 키는 자동으로 Index가 된다.
  • 필드 중에는 데이터 형식 때문에 Index가 될 수 없는 필드도 존재함
  • 여러 필드로 이루어진(다중 필드) Index를 사용하면 첫 필드 값이 같은 레코드도 구분할 수 있음

 

그렇다면 빠른 조회가 가능한 인덱스를 항상 만들지 않는 이유는 무엇일까? 당연한 소리지만 장점이 존재하면 단점 또한 존재한다.

먼저 인덱스를 만들면 별도의 저장 공간이 필요하기 때문에 .mdb 파일 크기가 늘어난다.

여러 사용자 응용 프로그램에서의 여러 사용자가 한 페이지를 동시에 수정할 수 있는 병행성이 줄어든다.

인덱스를 추가하면 쿼리 속도가 1초 정도 빨라지지만, 데이터 행을 추가하는 속도는 2초 정도 느려지게 되어 여러 사용자가 사용하는 경우 레코드 잠금 문제가 발생할 수 있다.

무조건 인덱스를 많이 설정한다고 성능이 향상되지 않는다. 조회 시 자주 사용하고 고유한 값 위주로 설정하는 것이 좋다.

인덱스는 항상 정렬된 상태를 유지하기 때문에 SELECT 문에는 효율적이지만 INSERT, DELETE, UPDATE 문에는 비효율적이다.

 

INSERT : 데이터를 추가하는 상황

  • 데이터를 추가할 때마다 인덱스는 정렬된 상태를 유지해야 하기 때문에 이에 따른 비용이 발생
  • 테이블에 데이터가 추가되면 상황에 따라 Index Split 과정을 거쳐야 하기 때문에 별도의 비용 발생
  • Index Split : B-tree index에서 새로운 index key가 들어왔을 때 기존에 할당된 블록 내에 저장할 영역이 없어 새로운 블록을 할당하는 것

 

DELETE : 데이터를 삭제하는 상황

  • 삭제가 발생하면 인덱스는 해당 데이터를 삭제하는 것이 아니라 '사용 안 함' 표시를 통해 구분
  • 데이터를 삭제하지 않기 때문에 인덱스의 메모리는 줄지 않음
  • 즉, 유효한 데이터보다 훨씬 많은 데이터들이 인덱스에 있을 수 있음

 

UPDATE : 데이터를 수정하는 상황

  • 인덱스에는 UPDATE의 개념이 없음
  • 데이터가 삭제(DELETE)되고 삭제된 자리에 새로운 데이터가 추가(INSERT)되는 개념임
  • 즉, DELETE, INSERT 연산이 모두 발생함

 

즉 인덱스는 데이터의 저장 성능을 감소시키고 데이터 읽기 성능을 향상시키는 자료구조이다.

인덱스는 테이블의 목적에 따라 다를 수도 있지만 보통 테이블당 3~5개 정도가 적당하다. 그렇다면 인덱스를 사용할 경우 어떤 컬럼에 인덱스를 설정하는 게 좋을까?

인덱스는 다음과 같은 4가지 기준을 사용하면 효율적으로 설정할 수 있다.

카디널리티(Cardinality) : 높을수록 좋음

  • 컬럼에 사용되는 값의 다양성 정도, 즉 중복 수치를 나타내는 지표
  • 한 컬럼이 갖고 있는 값의 중복 정도가 낮을수록 좋음

선택도(Selectivity) : 낮을수록 좋음

  • 데이터에서 특정 값을 얼마나 잘 선택할 수 있는지에 대한 지표
  • 5~10% 정도가 적당

활용도 : 높을수록 좋음

  • 해당 컬럼이 실제 작업에서 얼마나 활용되는지에 대한 지표
  • 수동 쿼리 조회, 로직과 서비스에서 쿼리를 날릴 때 WHERE 절에 자주 활용되는지를 판단

중복도 : 없을수록 좋음

  • 중복 인덱스 여부에 대한 지표

즉, 인덱스 역시 마찬가지로 상황에 따라 적절하게 활용해야 한다.

 

[ Reference ]

· https://goodgid.github.io/What-is-Index/

· https://yurimkoo.github.io/db/2020/03/14/db-index.html

 

반응형

'Computer Science > 데이터베이스' 카테고리의 다른 글

개인키(대칭키) vs 공개키(비대칭키)  (0) 2021.07.10
NoSQL  (0) 2021.07.10
DML - JOIN  (0) 2021.07.10
키(Key)의 종류  (0) 2021.07.09
SQL의 분류와 사용법  (0) 2021.07.09

댓글