sol 개발 블로그 로고
Published on

Index 개념 정리

Authors
  • avatar
    Name
    Chan Sol OH
    Twitter

목차

DB에서 Index란?

DB에 데이터가 많이 쌓이면 읽기 작업을 할 때 모든 데이터를 검색하면 시간이 오래걸린다. 검색 시간을 효과적으로 하기 위해 인덱스라는 것을 만들어서 사용한다.

인덱스는 컬럼을 사전에 조건에 따라 정렬시켜놓고 저장해놓은 테이블이다. 다만, 새롭게 테이블을 만들다 보니 공간활용이 늘어나고, 쓰기 작업할 때마다 리인덱싱을 해야하기 때문에 쓰기 시간이 오래 걸릴 수 있다. 그러므로 인덱스는 정말 많이 사용하는 조건 2~3개에 대해 만들어놓는 것이 좋다.

인덱스의 구현은 해싱 방식과 트리 방식을 사용한다.

인덱싱 기준

예를 들어 테이블에 성별 컬럼의 데이터가 남과 여로 5대5로 있고, 지역 컬럼이 전국 8도로 나눠져있다면, 비교적 세세한 조건인 지역 칼럼으로 인덱스를 만들어서 그룹핑하는게 효율적이다. 위와 같이 세세한 조건인 지역은 Cardinality가 높고, 중복성이 낮기에 인덱싱 조건으로 적합하다.

그럼 왜 Cardinality가 높고, 중복성이 낮은게 좋을까? 예를 들어 총 데이터 수량이 1만개일 때,

  • 성별로 인덱싱했을 때, 5천개 중 조건에 맞는 것을 검색함
  • 지역으로 인덱싱했을 때, 1250(10000/8)개 중 조건에 맞는 것을 검색함 조건에 맞는 검색은 인덱싱 그룹 전체를 탐색해야한다면, 두번째가 더 적게 탐색하므로 더 효율적이다.

대신 후보키처럼 과하게 세세하다면, 인덱싱 그룹을 찾는데 오래걸릴 것이므로 적절한 중간지점을 찾는 것이 중요하다. 또한 Primary key를 적용한 테이블은 자동으로 인덱스를 생성(클러스터드 인덱스)하기 때문에 또 인덱스를 생성할 필요없다.

Index, 장단점은?

  • 장점
    • 조건에 따라 미리 그룹핑된 테이블에 접근하므로, WHERE 절을 실행할 때 매번 전체 탐색하는 것 보다 효율적이다.
  • 단점
    • 새로운 테이블을 만들기 때문에 공간효율성이 낮아진다.
    • 테이블에 행 삽입이 있을 때, 그 테이블에 따른 인덱스에도 행이 추가되어야하므로, 쓰기 작업 시간이 길어진다.
    • 특히 관계형 DB는 쓰기 transaction 중에 읽기 작업이 제한되기 때문에 DB 성능이 떨어진다.

B-tree

binary search tree

위 이미지처럼 두갈래로 나뉘어서 부모 노드 보다 더 크면 오른쪽, 작으면 왼쪽으로 자녀 노드를 생성하는 것을 binary search tree라고 한다.

만약 데이터가 엄청 많아지면, 노드 수가 많아지고 깊이는 엄청 깊어질 것이다. 그래서 노드에 데이터를 2~3개씩 넣어두면 노드 수를 훨씬 줄일 수 있고, 깊이도 얕게 만들 수 있다. 이를 B-tree라고 한다.

B+tree

데이터를 노드마다 보관하는 것이 아니라 맨 밑 leaf 노드에만 보관하고 나머지 노드에는 데이터 탐색 가이드(조건)만 있다. 또한 맨 밑 노드끼리 분리되는 것이 아니라, 연결시켜줘서 범위 탐색을 더 쉽게할 수 있게했다.

범위 탐색이 쉬워지는 이유

  • leaf 노드끼리 분리돼있으면, 범위 탐색을 할 때 leaf 노드에서 부모 노드로 이동하고 다시 다른 leaf 노드로 이동해야한다.
  • 이동시간이 길어지면 탐색 시간이 길어지게 된다.
  • leaf 노드끼리 연결돼있으면, 범위 탐색을 할 때 다름 leaf 노드로 바로 이동해서 탐색하면된다.
  • 바로 이동할 수 있는 이유는 tree 구조로 데이터를 저장할 때 정렬을 해서 저장해놓기 때문에 바로 이동해도 괜찮다!!