본문 바로가기
정리

[DB] Index 정리

by baau 2023. 6. 13.

Index

  • 추가적인 쓰기 작업과 저장 공간을 활용하여 데이터베이스의 검색 속도를 향상하기 위한 자료구조
  • Index를 통해 검색 속도 향상과 조회 성능을 높일 수 있다.
  • Index를 사용하지 않는 칼럼을 조회하는 상황에서는 테이블 전체를 탐색하는 Table Full Scan이 수행되어 처리 속도가 떨어진다.
  • 인덱스를 활용하면, SELECT 외에도 UPDATE와 DELETE 성능을 향상할 수 있다.
    • UPDATE와 DELETE의 WHERE문에서 데이터를 조회하는 성능을 향상된다.

 

Index 적용 예시

// single column index
CREATE INDEX si_id ON MEMBER (id);
CREATE INDEX si_name ON MEMBER (name);

// multi column index
CREATE INDEX mi_id_name ON MEMBER (id, name); 
CREATE INDEX mi_id_name_age ON MEMBER (id, name, age);

 

Index 관리

  • Index를 관리하기 위해서는 데이터베이스의 약 10%의 저장공간이 필요하다.
  • Index는 항상 최신의 정렬된 상태로 유지해야 원하는 데이터를 빠르게 탐색할 수 있다.
  • 따라서 Index에 적용된 칼럼에 INSERT, UPDATE, DELETE가 수행된다면, Index를 관리를 위한 추가적인 연산이 발생하여 그에 따른 오버헤드가 발생한다.
    • INSERT : 인덱스 페이지(데이터가 저장되는 단위)가 꽉차면, 비어있는 페이지를 확보하고 문제 있는 페이지를 분할하는 과정에서 성능에 영향을 준다.
    • DELETE : 데이터를 실제 지우지 않고 "사용하지 않음" 처리를 한다.
    • UPDATE : DELETE - INSERT 순으로 동작한다.
  • DELETE와 UPDATE가 빈번하게 일어나는 칼럼에 대해서 index를 설정하면, 인덱스의 크키가 비대해져 성능을 오히려 저하시킨다.
    • DELETE와 UPDATE시 기존의 인덱스를 삭제하지 않고 “사용하지 않음” 처리(삭제마킹)를 하기 때문에 인덱스의 크기가 커져, 처리 성능이 떨어진다.

 

어떤 칼럼에 Index를 설정하는 것이 좋을까?

  • 수정 빈도 : UPDATE, DLELTE가 자주 발생하지 않는 칼럼
  • 활용도 : Join과 where, order by에 자주 사용하는 칼럼
  • 중복도 : 데이터의 중복도가 낮은 칼럼 (카디널리티가 높음)

 

Index 장단점

  • 장점
    • 특정 칼럼에 대해서 조회 시, 검색 속도 성능을 향상할 수 있다.
    • 전반적인 시스템 부하를 줄일 수 있다.
  • 단점
    • 인덱스를 관리하기 위해 DB의 10%의 저장공간이 필요하다.
    • 인덱스 관리를 위한 추가 작업이 필요하다.
    • 인덱스를 잘못 사용할 경우 성능이 저하되는 역효과가 발생한다.

 

Index 자료구조

  • 해시 테이블
    • Key, Value로 데이터를 저장하는 자료구조로, 빠른 데이터 검색이 필요할 때 유용하다.
    • 데이터베이스에서는 부등호(>, <)이 자주 일어나기 때문에, 등호(=) 연산에 특화된 해시테이블은 인덱스 자료구조로 적합하지 않다.

  • B+ Tree
    • DB의 인덱스를 위해 자식 노드가 2개 이상인 B-Tree를 개선시킨 자료구조
    • 리프 노드만 인덱스와 함께 데이터를 저장하고 있고, 나머지 노드는 데이터를 위한 인덱스만 갖는다.
    • 리프 노드는 Linked List로 연결되어 있다.
    • 데이터 노드 크기는 인덱스 노드의 크기와 같지 않아도 된다.
      • 인덱스는 삭제되지 않고, 비활성화 처리되기 때문에 데이터 노드의 크기와 인덱스 노드의 크기가 다를 수 있다.
    • 데이터 베이스의 인덱스 칼럼은 부등호를 이용한 순차 검색 연산이 자주 발생한다. 따라서 B+ Tree의 리프 노드들을 Linked List로 연결하여 순차검색을 용이하게 하는 등 BTree를 인덱스에 맞게 최적화한 것이다.

 

Index 주의사항

  • 인덱스로 사용될 칼럼값 그대로 사용해야만 인덱스가 사용된다.
    • WHERE salary * 10 > 15000 (인덱스 적용 X)
    • WHERE salary > 15000 / 10 (인덱스 적용 O)
  • 복합 인덱스 순서가 중요하다. (앞 순서의 조건은 반드시 포함시켜야 한다.)
    • 다음 칼럼이 이전 칼럼에 의존하여 정렬된다. 따라서 두 번째 칼럼만으로 질의를 하는 경우 인덱스를 잘 타지 못한다.
  • 하나의 쿼리는 여러 인덱스 테이블을 동시에 탐색하지 않고 하나의 인덱스만 탐색한다. 
  • 의도대로 인덱스가 동작하지 않을 경우 explain으로 확인
    • 옵티마이저의 실행 계획을 확인
    • 개발환경, 배포환경의 통계 내역이 다르기 때문에 따문에 옵티마이저 실행 계획이 다를 수 있다.
  • 인덱스는 PK에 의존하기 때문에, PK 값이 클수록 한 페이지에 담을 수 있는 인덱스 정보가 줄어들고, 메모리를 비효율적으로 사용되기 때문에 성능에 좋지 않다.

 

클러스터링 인덱스 & 넌클러스터링 인덱스

  • 클러스터링 인덱스
    • 인덱스로 지정한 컬럼을 기준으로 물리적으로 정렬하는 인덱스
    • 우선순위 : 1) primary key 2) unique + not null
    • 실제 데이터 자체가 정렬되어 있다.
    • 테이블당 1개만 존재 가능하다.
    • 검색속도는 빠르지만, 입력, 수정, 삭제는 느리다.
  • 넌클러스터링 인덱스
    • 데이터 자체는 정렬되지 않고, 인덱스값을 기준으로 정렬하여 새로 인덱스 페이지를 만드는 인덱스
    • 새로 인덱스 페이지를 만들고 리프 페이지에 실제 데이터가 위치한 주소를 가리킴
    • unique column, unique index, index 생성
    • 테이블당 여러개 존재 가능
    • 검색 속도는 Cluster에 비해 느리지만, 입력, 수정, 삭제가 빠르다.

 

테이블 스캔

  • Table Full Scan
    • 테이블에 속한 블록 전체를 읽어서 사용자가 원하는 데이터를 찾는다.
  • Index Range Scan
    • 인덱스 칼럼이 가공되지 않는 상태로 조건절에 있을 때 수행
    • 인덱스의 일정량을 스캔하면서 얻은 ROWID를 사용해 테이블 레코드를 찾는다.
  • Index Full Scan
    • 인덱스 칼럼이 조건에 없으면 Index Range Scan이 불가능하므로, 옵티마이저는 Table Full Scan을 고려한다.
    • 그런데 대용량 테이블이라면 Table Full Scan에 대한 부담이 너무 크면 Index를 활용할 필요가 있다.
    • 인덱스의 전체 크기는 테이블의 전체 크기보다 훨씬 적으므로, Index Range Scan을 할 수 없을 때 Full Table Scan보다는 Index Full Scan을 고려한다.