본문 바로가기
Research/Database

DB의 인덱스란

by RIEM 2023. 2. 26.

인덱스 란?

인덱스는 DB가 테이블을 검색하는 속도를 높여주는 자료 구조다.

특정 컬럼에 인덱스를 만들어 준다. 그 컬럼의 데이터들을 정렬해서 별도의 메모리 공간에 데이터의 물리적 주소와 함께 저장된다.

사용 방법은 인덱스로 가서 -> 인덱스에 저장된 데이터의 물리적 주소를 참조 -> 진짜 데이터의 주소로 가서 데이터를 가져오는 방식이다. 복잡해 보이지만 검색 속도 향상이 높아진다고 한다.

Screen Shot 2023-02-24 at 8 27 36 PM


(도표 출처 : https://coding-factory.tistory.com/746)

인덱스는 일종의 책의 목차다. 특정 내용을 찾기 위해 책을 바로 넘기기 전에 목차를 먼저 참고하는 것이 검색 속도를 높여주는 것과 동일한 원리다.

DB 작업에서 속도 저하 상황의 대부분은 Select문(+ Where절)에서 발생한다. 이에 대한 대안으로 Index를 주로 사용한다고 한다.

Index의 장점

Index의 강점은 데이터들이 정렬되어있다는 점인데 이로 인해 조건 검색을 빠르게 해준다.

조건 Where 절 효율 증가

보통 테이블에 데이터가 저장될 때는 이름 순서대로 차곡차곡 쌓이는 것이 아니라 뒤죽박죽으로 저장된다. 이로 인해 Where절로 데이터를 찾으려면 처음부터 끝까지 traverse하면서 조건에 맞는 데이터인지를 체크하는 지루한 절차(Full Table Scan)를 거치게 된다.
But 인덱스 테이블은 이미 정렬되어있기에 바로 조건을 찾을 수 있다.

정렬 Order by 절 효율 증가

Order by 또한 부하가 많은 작업이다. 정렬 동시에 1차적으로 메모리에서 정렬되고, 만약 메모리보다 큰 작업을 요구할 경우, 디스크 I/O도 추가적으로 발생한다.
But 인덱스 테이블은 이미 정렬되어있어 바로 찾아올 수 있다.

Min, Max의 효율 증가

정렬이 되어있으면 시작과 끝을 알기 위해 테이블을 뒤질 필요가 없다.

Index의 단점

인덱스 테이블은 레코드 내 데이터 값이 바뀔 경우 문제가 발생한다. 왜냐하면 인덱스 테이블을 정렬된 상태를 계속 유지해줘야 하기 때문이다.

문제는 3개인데

  1. CRUD 작업으로 인해 레코드가 바뀌면 인덱스 테이블을 재정렬 해줘야 한다
  2. 인덱스 테이블과 원본 테이블 둘 다 최신화해주어야 한다
  3. 인덱스 관리를 위해 DB의 약 10%에 해당하는 저장공간이 추가로 필요

블로그에 따르면 통상적으로 전체 데이터 중 10~15% 이하 데이터를 처리할 경우에 인덱스 테이블이 효율적이다고 한다. 그 이상 데이터 처리 시 차라리 full table scan이 유리하다고 한다.(출처 : https://coding-factory.tistory.com/746)

만약 지속적인 관리로 인한 부하를 최소화하고 싶다면, 데이터 삭제 대신 -> 인덱스 사용하지 않는 방식으로 접근할 수도 있다.

  • Insert : 새 데이터에 대한 인덱스 추가
  • Delete : 삭제 데이터의 인덱스는 따로 삭제하지 않고, 그냥 방치한다
  • Update : 기존 인덱스는 '사용하지 않음' 처리 -> 갱신 데이터에 대한 인덱스 추가

인덱스 생성 전략

그렇다면 무엇을 인덱스로 생성하는가? 데이터 분포도는 최대한 그리고 호출 빈도가 높은 컬럼을 인덱스로 생성하면 좋다. 인덱스는 특정 컬럼을 기준으로 생성하는데, 기준이 된 컬럼으로 정렬된 Index 테이블이 생성된다. 인덱스 테이블은 최적의 효율을 위해 중복값이 없는 PK로 하는 것을 추천한다.

어떤 컬럼이 좋은가?

  1. 조건절에 자주 등장하는 컬럼
  2. 항상 = 으로 비교하는 컬럼
  3. 중복되는 데이터가 최소한인 컬럼(분포도가 이쁜)
  4. Order by 절에서 자주 사용되는 컬럼
  5. 조인 조건으로 자주 사용되는 컬럼

인덱스 유형

인덱스에도 여러 유형이 있다. 그중 가장 많이 사용하는 것이 Balanced Tree Index 구조다. B Tree 또는 B*Tree 를 주로 사용한다고 한다.

Postgres는 B-Tree, Hash, GiST, SP-GiST, GIN, BRIN의 인덱싱 유형을 제공한다고 한다.

![[Pasted image 20230224211841.png]]
B Tree 출처 : https://www.geeksforgeeks.org/introduction-of-b-tree-2/

![[Pasted image 20230224212023.png]]
B*Tree 출처 : https://coding-factory.tistory.com/746

레퍼런스

'Research > Database' 카테고리의 다른 글

nestjs_cache-manager로 redis 사용하기  (0) 2023.02.27
DB_Redis 설치 및 명령어 Cheatsheet(Mac OS)  (0) 2023.02.27
DB_Optimistic Lock vs. Pessimistic Lock  (0) 2023.02.24
TypeORM_QueryBuilder_Select  (0) 2023.02.24
DB_ODM vs. ORM  (0) 2023.02.23

댓글