Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

README.md

RealMySQL 의 8장 인덱스를 읽고 정리

인덱스란?

  • 데이터파일에 저장된 레코드의 주소를 탐색할 수 있게 해주는 색인
  • 탐색이 용이하도록 인덱스는 정렬되어 보관된다.
  • 데이터를 추가, 수정, 삭제할 때마다 인덱스를 재정렬하기 위해 느려진다.
  • 반면 데이터를 조회할 때 인덱스를 타면 매우 빨라진다.

Primary Key 와 Secondary Key

  • Primary Key: 레코드를 대표하는 컬럼값으로 만들어진 인덱스. PK 가 곧 클러스터링 인덱스가 된다.
  • Secondary Key: Primary Key 를 제외한 모든 인덱스이다.

B-Tree 인덱스

  • DBMS 에서 인덱스를 구현하기 위해 B-Tree 자료 구조를 많이 사용한다.
  • B 는 Binary 가 아니라 Balanced 를 뜻한다.
  • root node, branch node, leaf node 3가지 node 로 B-Tree 가 구성된다.
  • leaf node 에는 실제 데이터 레코드를 찾아가기 위한 주소가 있다.
    • 즉 node 가 정렬되어 있는 것이지, 데이터 레코드 가 정렬되어 있는게 아니다.
  • InnoDB Primary Key 의 경우 클러스터링 인덱스라고 하여, 데이터 레코드가 PK 순서대로 정렬이 되어 있다.
  • InnoDB 의 Secondary Key 의 경우에는 leaf node 에 Primary Key 를 암시적으로 포함하고 있다.

B-Tree 인덱스 키 추가, 삭제, 수정

InnoDB 에서는 추가, 삭제, 수정에 대하여
체인지 버퍼를 통한 지연 처리를 지원한다.

  • 추가
    • 이미 만들어진 leaf node 를 탐색하여 추가를 한다.
    • 만약 leaf node 가 꽉 찼다면, 추가하는데 비용이 많이 든다.
  • 삭제
    • leaf node 탐색 후 삭제되었다고 표시만 한다.
  • 수정
    • 정렬을 해야하므로, leaf node 의 값을 변경하기 보다는, 아예 node 를 삭제 후 새로 추가하는 방법을 쓴다.

인덱스 키 검색

  • 인덱스 검색은 트리 노드 탐색을 통해 이루어지기 때문에 빠르다.
  • SELECT에서만 사용하는 것이 아니라 UPDATE, DELETE 처리하기 위해 레코드를 먼저 검색해야 할 경우에도 노드를 먼저 탐색해야한다.
  • B-Tree 인덱스는 100% 일치 또는 값의 앞부분만 일치하는 경우에 트리 탐색을 한다.
    • LIKE "%Search" 같은 경우 트리 노드 탐색이 불가능해서 풀스캔을 한다.

인덱스 사용에 영향을 미치는 요소

아래 3가지를 DBA 가 고민해볼만하다.

  • 인덱스를 구성하는 칼럼의 크기
  • 레코드의 건수
  • 유니크한 인덱스 키값의 개수

인덱스 키 값의 크기

  • 스토리지의 블록 사이즈와, DB 의 블록 사이즈를 비슷하게 맞춰주는 것이 좋다.
  • 블록이 모여서 페이지가 된다. root/branch/leaf node 또한 페이지이다.
  • 인덱스의 크기는 곧 node 의 크기이며, 블록의 배수가 될 수 있도록 해야한다.

선택도(기수성)

  • Cardinality = the number of cardinal (basic) members in a set
  • Selectivity = Cardinality / Total Number Of Records
  • Cardinality 는 클수록 좋다!
  • 다만, 정렬 혹은 Group by 를 자주하는 Column 일 경우, Cardinality 가 낮아도 인덱스를 걸 가치가 있다.

B-Tree 인덱스를 통한 데이터 읽기

인덱스 레인지 스캔

  • 빠르다.
  • 검색해야할 인덱스의 범위가 결정됐을 때 사용하는 방식이다.
  • 시작 위치(인덱스 탐색) 찾은 후 리프노드 간 링크를 통해 다음 리프노드를 찾아 스캔(인덱스 스캔)한다.
  • 정순 또는 역순으로 정렬된 상태로 레코드를 가져온다.

인덱스 풀 스캔

  • 느리다.
  • 인덱스의 처음부터 끝까지 모두 읽는 방식이다.

루스 인덱스 스캔

  • 느슨 하게 또는 듬성듬성 하게 인덱스를 탐색한다.
  • 인덱스 레인지 스캔과 비슷하게 동작하지만, 중간마다 필요치 않은 인덱스 키 값을 스킵한다.
  • 다음의 경우에 사용된다.
    • GROUP BY
    • MAX, MIN
    • 집합 함수

다중 칼럼(Multi-column) 인덱스

  • 두 개 이상의 칼럼으로 구성된 인덱스이다.
  • 두번째 컬럼은 첫 번째 칼럼에 의존해서 정렬된다.
  • 따라서 무엇을 첫번째로 할지, 순서가 중요하다.

R-Tree 인덱스

  • Rectangle Tree
  • MBR: Minimum Bounding Rectangle
  • Spatial Index (공간 인덱스) 라고 부르기도 한다.
  • 어떤 도형을 감싸는 최소 크기의 사각형을 인덱스로 삼는다.

R-Tree 인덱스의 용도

  • 공간관련, 두 점 사이의 거리가 요구사항에 있는 경우에 쓸 수 있다.
    • 예시: 현재 위치에서 가까운 카페 찾기
  • 다만 R-Tree 인덱스를 쓸 바에는 MySQL 말고 다른 DBMS 를 사용하는게 낫다.

클러스터링 인덱스

  • 클러스터링은 여러개가 하나로 묶인것을 뜻한다.
  • 클러스터링 인덱스는 레코드들이 PK 와 같은 정렬 방식으로 File에 저장되는 형태를 뜻한다.
  • 이유는 PK가 비슷한 인근값들을 동시에 조회하는 경우가 확률상 높다고 생각하기 때문이다.
  • 클러스터링 인덱스는 MyISAM 과 같은 다른 스토리지 엔진에서는 지원되지 않는다.
  • InnoDB 에서만 클러스터링 인덱스가 지원된다.
  • InnoDB 와 다른 스토리지 엔진의 차이를 면접 질문으로 물어본다면 클러스터링 인덱스에 대해 이야기해주자.

클러스터링 인덱스 키의 크기

  • PK 가 커지면, 다른 세컨더리 인덱스 전체도 크기가 커진다.
  • 왜냐하면 클러스터링 테이블의 경우 모든 세컨더리 인덱스가 PK 값을 가지고 있기 때문이다.
  • 인덱스가 커지면 같은 성능을 내기 위해 메모리또한 더 커져야하므로 InnoDB 테이블의 프라이머리 키는 신중하게 선택해야한다.

유니크 인덱스

  • 탐색보다는 "Unique" 제약 조건을 걸기 위해 사용된다.
  • 왜냐하면 MySQL 에서 INDEX 없이 유니크 제약을 설정하는건 성능에 안좋기 때문이다.

유니크 인덱스와 세컨더리 인덱스의 비교

  • 유니크 인덱스 읽기
    • 유니크 인덱스와 유니크하지 않은 인덱스 사이에 성능차이는 크지 않다.
    • 둘다 비슷한 DISK IO 가 발생하기 때문이다.
  • 유니크 인덱스 쓰기
    • 유니크 인덱스는 쓰기성능이 더 나쁘다.
    • 쓰기동작에서 중복인지 아닌지를 체크하기 위해 락이 걸리기 때문이다.