[DB] Index(인덱스)란?

yongkini ·2021년 9월 20일
0

DataBase

목록 보기
2/5

인덱스(Index)란?

: 실제 개발일을 할 때, SQL select문의 속도가 너무 느린 경우가 있었는데(레코드가 너무 많아서), 그 때, 해결방법으로 고려해봤던 것중 하나가 인덱싱을 하는 것이었다. 인덱스는 우리가 흔히 아는 색인과 같은 의미로 목차 역할을 한다. 원래 데이터를 검색하면 전체 데이터를 다 훑어봐야 특정 데이터를 찾아낼 수 있는데, 그 과정을 빠르게 하기위해 index라는 자료구조를 거쳐서 검색을 하는 것이다. 이 index라는 자료구조에는 데이터와 그 데이터의 주소값(pointer)이 키, 값으로 되어있고, 쿼리가 들어오면 이 index를 바탕으로 주소값을 통해 검색한다. 그리고 그렇게하면 검색속도가 훨씬 빨라진다.

: 보통 DBMS에 데이터를 저장하면 ArrayList 형태로 자료를 저장하는데(넣은 순서대로), 인덱스를 사용하면, 컬럼의 값과 실제 해당 자료가 저장된 주소를 '키-값'형태로 인덱스를 만들어둠으로써 항상 '정렬된 상태'를 유지하는 SortedList 형태로 자료를 저장할 수 있다. 사전에서도 ㄱ,ㄴ,ㄷ 순으로 정렬된 목차를 보고 쉽게 단어를 찾듯이 인덱스를 지정해놓으면 정렬된 상태를 유지하므로, select 쿼리문을 상대적으로 빨리 수행할 수 있다. 하지만, 항상 정렬된 상태를 유지하기 때문에 update, delete, insert문을 실행할 때는 상대적으로 느리게 수행하게 되는 단점이 있다.

인덱스 알고리즘 종류

  • B-Tree 알고리즘 : 칼럼의 값을 변형하지 않은채로 사용하는 인덱스 알고리즘. 가장 범용적으로 쓰이는 인덱스 알고리즘이지만, 앞에서 말했듯이 수정, 추가, 삭제에는 비효율적임

  • 해시 테이블 알고리즘 : B-Tree 알고리즘과는 다르게 컬럼의 값을 그대로 쓰지 않고, 값을 변형해서 쓰는 알고리즘. 해쉬 테이블의 특성과 같이 매우 빠른 검색을 지원하지만, 전방 일치와 같이 값의 일부만 검색할 때는 해시 인덱스를 사용할 수 없음!

  • Fractal Tree 알고리즘 : B-Tree 알고리즘과 같이 값을 변경하지 않고 쓰기에 범용적으로 사용할 수 있음과 동시에 비트리 알고리즘의 단점인 수정, 삭제, 추가가 느린 부분을 개선한 알고리즘

인덱스 사용의 장단점

<장점>

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

<단점>

  • 인덱스를 관리하기 위해 DB의 약 10%에 해당하는 저장공간이 필요하다.
  • 인덱스를 관리하기 위해 추가 작업이 필요하다.
  • 인덱스를 잘못 사용할 경우 오히려 성능이 저하되는 역효과가 발생할 수 있다(예를 들어, UPDATE, DELETE를 할 때 index에 자료를 삭제하지 않고, '사용하지 않음' 처리를 하기 때문에 이런 것들이 많아지면 자료가 비대해져서 오히려 성능이 저하됨+INSERT를 할 때 index 정보도 추가해야됨).

인덱스를 사용하면 좋은 상황

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

클러스터드 인덱스(Clustered Index)란?

: 클러스터(Cluster)는 여러개를 하나로 묶는다는 의미로 자주 쓰는데, 비슷한 것들을 묶어서 저장하는 형태로 쓰이는 것이 클러스터드 인덱스이다. 이는 조회를 할 때 주로 비슷한 것들을 같이 조회하는 경향이 있음에서 만든 것인데, 프라이머리키를 가지고 만들기 때문에 한 테이블당 하나만 만들 수 있다(일반 인덱스는 여러개 만들 수 있음). 이처럼 프라이머리키를 기준으로 비슷한 것들끼리 묶어서 저장하는 것을 클러스터드 인덱스라고 한다.

마무리

: 인덱스는 SELECT 쿼리시에 수행 속도를 월등히 빠르게 한다는 점에서 효율적이지만, 앞서 말했듯이 수반되는 단점들이 오히려 장점을 넘어서 비효율적으로 만들 수 있기 때문에 상황에 따라 알맞게 사용해야한다. 예를 들어, 이름, 나이, 성별의 컬럼이 있을 때, 나이에 대해서 인덱스를 이용하면, 어차피 나이에 대해 인덱스를 걸어놔도 나이 자체가 월등히 유니크한 값이 아니기 때문에 또다시 디스크I/O가 발생한다. 그러나, 이름에 대해서 인덱스를 걸어놓으면 이름은 매우 유니크한 값이기에 훨씬 효율적이다(인덱스를 쓴다는 관점에서).

profile
완벽함 보다는 최선의 결과를 위해 끊임없이 노력하는 개발자

0개의 댓글