Home /Database/ 인덱스
Post
Cancel

/Database/ 인덱스



1. 인덱스


  • 인덱스란 추가적인 쓰기 작업과 저장 공간을 활용
    데이터베이스의 읽기 작업을 향상하기 위한 자료구조
  • 책에 있는 색인이 특정 키워드가 어느 페이지에 위치하는지 알려주는 것처럼
    인덱스를 이용하면 특정 데이터가 테이블 중 어디에 위치하는지 빠르게 찾을 수 있어
    데이터베이스 테이블의 검색 속도를 향상시켜 준다.


✔️ 인덱스가 없는 것과 인덱스가 있는 것

  • FTS(Full Table Scan)
      - 인덱스 없이 모든 테이블을 샅샅이 조회하는 것
      - 많은 정보를 찾을 때 유리함
  • Index Scan
      - 인덱스를 사용하여 범위를 좁혀가는 것
      - 최종 몇 개의 정보를 찾을 때 유리함



1-1. 인덱스의 원리


특정 컬럼에 인덱스를 생성하면,
해당 컬럼의 데이터들을 정렬하여
별도의 메모리 공간에 데이터의 물리적 주소와 함께 저장되고,

인덱스가 생성 되었다면
생성한 인덱스의 컬럼을 Where 조건으로 쿼리하면
옵티마이저에서 판단하여 생성된 인덱스를 타게 된다.
그러면 인덱스에 저장되어 있는 데이터의 물리적 주소로 가서 데이터를 가져온다.

✔️ 쿼리

  • 웹 서버에 특정한 정보를 보여달라는 웹 클라이언트 요청(주로 문자열을 기반으로 한 요청이다)에 의한 처리
  • 쿼리는 대개 데이터베이스로부터 특정한 주제어나 어귀를 찾기 위해 사용된다.
  • 주제어가 검색엔진의 검색필드 내에 입력된 다음, 그 내용이 웹 서버로 넘겨진다.

✔️ 옵티마이저

  • SQL을 가장 빠르고 효율적으로 수행할 최적의 처리경로를 생성해 주는 DBMS 내부의 핵심 엔진
  • 사용자가 구조화된 질의어(SQL)로 결과 집합을 요구하면,
      이를 생성하는데 필요한 처리경로는 DBMS에 내장된 옵티마이저가 자동으로 생성해준다.
  • 옵티마이저가 생성한 SQL 처리경로를 실행계획(Execution Plan)이라고 한다.



1-3. 인덱스의 장점


테이블의 데이터들이 정렬되어 있어 조건 검색을 하는 것에 효율을 높여준다.


조건 검색 Where절의 효율성

일반적으로 테이블을 만들고 안에 데이터가 쌓이게 되면
테이블의 레코드는 내부적으로 순서가 없이 뒤죽박죽으로 저장된다.

이렇게 되면 Where절에 특정 조건에 맞는 데이터들을 찾아낼때도
레코드의 처음부터 끝까지 다 읽어서 검색 조건과 맞는지 비교해야 한다.
이것을 풀 테이블 스캔 (Full Table Scan)이라고 한다.

하지만 인덱스 테이블은 데이터들이 정렬되어 저장되어 있기 때문에 해당 조건 (Where)에 맞는 데이터들을 빠르게 찾아낼 수 있다.
이것이 인덱스(Index)를 사용하는 가장 큰 이유이다.


정렬 Order by절의 효율성

일반적으로 Order by는 굉장히 부하가 많이 걸리는 작업이다.
정렬과 동시에 1차적으로 메모리에서 정렬이 이루어지고
메모리보다 큰 작업이 필요하다면 디스크 I/O도 추가적으로 발생된다.

하지만 인덱스를 사용하면 이미 정렬되어 있기 때문에
Order by에 의한 Sort과정을 피할수가 있고,
위에서 말한 전반적인 자원 소모를 하지 않아도 된다.

✔️ 디스크 I/O

  • 웹 서비스 성능에 많은 영향을 미치는 중요 모니터링 지표
  • Disk I/O는 웹 서비스에 영향을 주는데,
      그 이유는 디스크의 데이터 처리 속도가 메모리나 CPU에 비해 너무 느리기 때문이다.


MIN, MAX

이미 데이터가 정렬되어 있기 때문에
MIN값과 MAX값을 레코드의 시작값과 끝 값 한건씩만 가져오면 된다.

FULL TABE SCAN으로 테이블을 다 뒤져서 작업하는 것보다 훨씬 효율적으로 찾을 수 있다.



1-4. 인덱스의 단점


(모든 요소에 인덱스를 걸지 않는 이유 - 분포도)

인덱스를 사용하면 테이블을 검색하는 속도와 성능이 향상되는 장점이 있지만
인덱스를 관리하기 위한 추가 작업이 필요하며, 추가 저장 공간 또한 필요하다.
잘못 사용하는 경우 오히려 성능이 저하될 수 있다.

  • 인덱스가 적용된 칼럼에 삽입, 삭제, 수정이 잦다면
    인덱스 또한 수정해야 하기 때문에 성능이 낮아질 수 있다.

  • 인덱스를 삭제했을 때 인덱스가 제거되는 것이 아니라 ‘사용하지 않음’으로 남겨 두기 때문에
    인덱스가 과도하게 커질 수 있다.



2. 복합(결합) 인덱스


  • 두 개 이상의 컬럼을 합쳐 인덱스를 만드는 것
  • 단일 컬럼으로는 나쁜 분포도를 가지지만
    여러 개의 컬럼을 합친다면 좋은 분포도를 가질 수 있다.
  • Where절에서 AND 조건에 많이 사용되는 컬럼들을 결합 인덱스로 구성

✔️ 분포도

  • 특정 데이터 집합의 Unique한 값의 개수
  • 분포도가 낮음 = 인덱스로 사용하기 좋음



2-1. 복합인덱스를 사용하는 경우

  • where절에서 and 조건으로 자주 결합되어 사용되면서 각각의 분포도 보다 두 개 이상의 컬럼이 결합될 때 분포도가 좋아지는 컬럼들
  • 다른 테이블과 조인의 연결고리로 자주 사용되는 컬럼들
  • order by에서 자주 사용되는 컬럼들
  • 하나 이상의 키 컬럼 조건으로 같은 테이블의 컬럼들이 자주 조회될 때



2-2. 효율적인 결합 인덱스 컬럼 설정


컬럼의 순서를 잘못 배열하면 결합 인덱스의 발동 확률이 매우 낮아질 수 있기 때문에 반드시 결합 인덱스의 컬럼 중 선행하는 컬럼부터 조건에 지정하여 사용해야 한다.

  1. where절 조건에 많이 사용되는 컬럼이 우선시
  2. Equal(‘=’)로 사용되는 컬럼 우선
  3. 분포도가 좋은 컬럼을 우선
  4. 자주 이용되는 순서대로 결합 인덱스 컬럼의 순서 결정

순으로 설정하여야 하면 효율적으로 인덱스를 결합할 수 있다.



3. 선택성/분포도



Selectivity, 선택성
cardinality, 분포도


  • NDV(Number of Distinct Value)
     : 특정 컬럼에 Unique한 값이 얼마나 있는지를 얘기하는 것
  • 밀도(Density)
     : 선택도 = 1 / NDV
  • 선택도(Selectivity)
     : 전체 레코드 중에서 조건절에 의해 선택될 것으로 예상되는 레코드의 비율(%)
     (선택도 = 카디널리티 / 총 레코드 수)
  • 카디널리티(분포도)
     : 특정 데이터 집합의 Unique한 값의 개수
     (카디널리티 = 선택도 * 총 레코드 수)


  • 선택성
    • 선택성이 좋음 = 인덱스로 사용하기 좋음
    • 선택성이 좋다는 것은
      수많은 데이터의 속에서 원하는 값만을 꺼낼올 수 있는 확률이 높다는 것
    • 선택성이 좋으려면 분포도가 낮아야 한다.
  • 분포도
    • 분포도가 낮음 = 인덱스로 사용하기 좋음
    • 분포도가 낮다는 것은
      자료가 밀집되어 있지 않고 중복이 적다는 의미


  • 분포도가 높은 예
    남자/여자로 나누는 경우 모집단의 반반으로 나뉘는 것 말고는 별 소득이 없을 것이다.


선택성이 좋다 = 분포도가 낮다 = 인덱스로 사용하기 좋다
분포도가 높다 = 선택성이 나쁘다 = 인덱스로 사용하기 안좋다




(참고링크)



공부한 내용을 여러글과 책 읽은 내용을 바탕으로 정리하고 있습니다.
좋은 글로 저의 공부에 도움을 주시는 분들께 감사드립니다.

This post is licensed under CC BY 4.0 by the author.