[Database] 인덱스(Index)란?

김강욱·2024년 6월 1일
0

Database

목록 보기
8/11
post-thumbnail

이번 포스팅에서는 인덱스(Index)에 대해 알아보려고 합니다.

😁 인덱스(Index)란?

인덱스는 추가적인 쓰기 작업과 저장 공간을 활용하여 데이터베이스 테이블의 검색 속도를 향상시키기 위한 자료구조입니다. 예를 들어, 책에서 원하는 내용을 찾기 위해 책의 모든 페이지를 찾는 것 보다 앞에 목차를 이용하여 원하는 페이지를 찾는 것이 훨씬 시간적을 절약됩니다. 데이터베이스에서도 테이블의 모든 데이터를 검색하면 시간이 오래 걸리기 때문에 데이터와 데이터의 위치를 포함한 자료구조를 생성하여 빠르게 조회할 수 있도록 돕고 있는 것이 바로 인덱스입니다.

특정 컬럼에 인덱스를 걸면 해당 컬럼의 데이터들은 정렬되어 별도의 메모리 공간에 데이터의 물리적 주소와 함께 저장됩니다. 인덱스를 사용하면 DB를 순차 검색(Full Scan)하기 전에 인덱스에 조회하고자 하는 데이터가 있는지 먼저 확인하고 있을 시 데이터의 물리적 주소로 이동해 데이터를 가져오며 그렇지 않을 경우 DB를 순차 검색하는 방식으로 동작합니다.

인덱스와 테이블의 관계 - 사진 출처 : 망나니개발자님의 [Database] 인덱스(index)란?


✈️ 인덱스(Index)의 특징

📌 인덱스의 장점

인덱스를 사용하면 테이블을 조회하는 속도와 그에 따른 성능을 향상시킬 수 있고 전반적인 시스템의 부하를 줄일 수 있습니다.

인덱스를 활용했을 시, 데이터를 조회하는 SELECT 외에도 UPDATEDELETE의 성능이 함께 향상됩니다. 해당 연산을 수행하기 위해서 대상을 조회해야만 작업을 처리할 수 있습니다. 만약 인덱스를 사용하지 않은 컬럼을 조회해야 하는 상황이라면 전체를 탐색하는 Full Scan을 수행하기 때문에 처리 속도가 떨어집니다. 그렇기에 인덱스를 사용하여 조회 성능을 개선하고 그로 인한 부가적인 UPDATE, DELETE 쿼리의 성능도 개선되게 됩니다.

📌 인덱스의 단점

인덱스를 관리하기 위해 DB의 약 10%에 해당되는 저장 공간이 필요합니다. 또한 인덱스를 관리하기 위해 추가 작업이 필요하고 인덱스를 잘못 사용할 경우 오히려 성능이 저하되는 역효과가 발생할 수 있습니다.

DBMS는 인덱스를 항상 최신의 정렬된 상태로 유지해야 원하는 값을 빠르게 탐색할 수 있기 때문에 인덱스가 적용된 컬럼에 INSERT,UPDATE, DELETE가 수행된다면 추가 연산 및 그에 따른 오버헤드가 발생하게 됩니다. 즉, INSERT 작업 시 새로운 데이터에 대한 인덱스를 추가해줘야 하고, DELETE 작업 시 삭제하는 데이터의 인덱스를 사용하지 않는다는 작업을 진행해야 하며, UPDATE 작업 시 기존의 인덱스를 사용하지 않음 처리하고, 갱신된 데이터에 대해 인덱스를 추가해줘야 작업이 따로 필요합니다.

또한 UPDATEDELETE가 빈번하게 발생하는 속성에 인덱스를 걸게 되면 인덱스의 크기가 비대해져서 성능이 오히려 저하되는 역효과가 발생할 수 있습니다. UPDATEDELETE는 기존의 인덱스를 삭제하지 않고 사용하지 않음 처리를 해주는데 이로 인해 실제 데이터보다 훨씬 많은 인덱스가 존재하게 되어 쿼리문 처리 시 성능이 떨어질 수 있습니다.


📌 인덱스 사용하기 좋은 조건

  1. INSERT, UPDATE, DELETE가 자주 발생하지 않는 컬럼
  2. JOIN, WHERE, ORDER BY에 자주 사용되는 컬럼
  3. 데이터의 중복도가 낮은 컬럼
  4. 전체 데이터 중 10 ~ 15 % 이하의 데이터를 처리하는 경우

인덱스를 사용하면 조건 검색 쿼리의 효율성 뿐만 아니라 정렬에서도 다른 이점이 존재합니다. 기본적으로 데이터 정렬은 굉장히 부하가 걸리는 작업인데, 인덱스는 미리 데이터를 정렬해 관리하기 때문에 Order by에 의한 정렬 과정을 생략할 수 있습니다. 예를 들어, B-트리 인덱스는 노드들이 특정 키 값에 따라 정렬된 상태를 유지합니다. 즉, 인덱스가 생성되면 해당 컬럼의 데이터가 인덱스 내에서 항상 정렬된 상태로 유지된다는 의미입니다. ASC가 기본으로 정렬된 순서라면 DESC는 인덱스를 거꾸로 읽어올 수 있기 때문에 정렬이 따로 필요없습니다.

또한 데이터가 이미 정렬되어 있으므로 최댓값과 최솟값을 인덱스 레코드의 시작값과 끝값으로 쉽게 가져올 수 있다는 장점도 있습니다.

또한 인덱스에는 데이터의 카디널리티가 높은 컬럼을 선정하는 것이 좋습니다. 예를 들어, 성별이라는 컬럼에 인덱스를 걸었다고 하면 남자와 여자라는 도메인만 존재하기 때문에 탐색할 수 있는 값이 2개 밖에 없으므로 검색할 값이 중복되고 그만큼 검색할 대상이 증가하게 됩니다. 그러므로 가능한 데이터의 중복도가 낮아 분포도가 높은 컬럼에 인덱스를 사용하는 것이 좋습니다.


📌 인덱스의 분류

  1. 클러스터 인덱스 : 테이블의 PK에 적용되는 인덱스
  2. 비클러스터 인덱스 : 테이블의 PK 이외의 컬럼에 적용되는 인덱스
  3. 유니크 인덱스 : PK는 아니지만 Unique 속성을 가진 컬럼에 적용되는 인덱스 (Nullable 할 수도 있습니다)

대부분의 경우에는 PK에 인덱스를 걸어주는 것이 좋습니다.


📝 인덱스(Index)의 자료구조

✔️ 해시테이블 인덱스

해시 테이블(Key, Value) 구조로 데이터를 관리하며 해시 함수를 기반으로 Key 값을 생성하는 자료구조입니다. Key에 해당하는 Value를 찾기 위해 해시 함수를 한 번만 실행하면 된다는 점에서 빠른 조회 연산을 보장하고 있습니다.

📌 해시테이블의 인덱스 장단점

해시 인덱스는 트리 내에서 여러 노드를 읽어야만 데이터를 찾을 수 있는 B+Tree보다 검색 속도가 빠릅니다. 또한 데이터에 해시 함수를 적용하여 저장하기 때문에 키 값의 크기가 줄어들어 가용성이 좋습니다.

하지만, 부등호를 이용한 조건 조회가 불가능합니다. 해시 인덱스는 해시 함수를 기반으로 데이터를 검색하기 때문에 데이터를 정렬하지 않습니다. 그러므로 부등호를 사용한 검색 조건에 있어서는 해시 인덱스를 활용할 수 없는 단점이 있습니다.

해시테이블 인덱스 - 사진 출처 goodGid님의 해시(Hash) 테이블 개념과 방식


✔️ B+Tree 인덱스

가장 많이 사용되는 인덱스의 구조이며 자식 노드가 2개 이상인 B-Tree를 개선시킨 자료구조 형태입니다. B+Tree는 다음과 같은 요소로 구성되어 있습니다.

1. Root node : 검색 경로의 출발점
2. Leaf node : 실제 검색할 데이터가 저장된 노드
3. Non-leaf node : Leaf node까지 가기 위해 다음 경로 노드의 Key 값을 가지고 있는 노드
4. LinkedList : 부등호를 이용한 순차 검색 연산이 용이하도록 Leaf node들을 LinkedList로 연결

SELECT 쿼리를 날리면 Root node에서 시작하여 Non-Leaf nodes를 거쳐 실제 데이터의 주소가 존재하는 Leaf node를 검색합니다.

B+Tree 예시 - 사진 출처 혀내님의 [DB] 인덱스(Index)로 DB 검색 속도를 높여보자


⚙️ 인덱스(Index)의 사용 명령어


인덱스 생성

# CREATE INDEX [인덱스명] ON [테이블명](컬럼1, 컬럼2, 컬럼3, ...);
CREATE INDEX A_INDEX ON A(AID, TITLE);

인덱스 조회

SELECT * FROM A_INDEX WHERE AID = 3L;

인덱스 삭제

DROP INDEX A_INDEX;

너무 많은 인덱스를 생성하는 것은 INSERT, UPDATE, DELETE 시 부하가 발생해 전체적인 DB 성능을 저하시키는 요인이 될 수 있습니다. 그러므로 사용하지 않는 인덱스는 즉시 삭제하는 것이 좋습니다.

☕ 마치며

이번 포스팅에서는 인덱스에 대해 알아보았습니다. 쿼리 성능 개선에 대해 찾아보면 빠질 수 없는 주제 중 하나가 인덱스입니다. 그렇다고 무조건적으로 인덱스를 적용하는 게 아니라 해당 테이블 컬럼의 환경 조건에 따라 알맞게 적용하는 것이 중요하다고 생각합니다. 인덱스를 이해하는데 많은 도움을 주신 혀내님, 망나니개발자님께 감사를 표합니다.


참고 자료
혀내님의 [DB] 인덱스(Index)로 DB 검색 속도를 높여보자
망나니개발자님의 [Database] 인덱스(index)란?

profile
TO BE DEVELOPER

0개의 댓글

관련 채용 정보