- 데이터파일에 저장된 레코드의 주소를 탐색할 수 있게 해주는 색인
- 탐색이 용이하도록 인덱스는 정렬되어 보관된다.
- 데이터를 추가, 수정, 삭제할 때마다 인덱스를 재정렬하기 위해 느려진다.
- 반면 데이터를 조회할 때 인덱스를 타면 매우 빨라진다.
- Primary Key: 레코드를 대표하는 컬럼값으로 만들어진 인덱스. PK 가 곧 클러스터링 인덱스가 된다.
- Secondary Key: Primary Key 를 제외한 모든 인덱스이다.
- 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 를 암시적으로 포함하고 있다.
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 가 낮아도 인덱스를 걸 가치가 있다.
- 빠르다.
- 검색해야할 인덱스의 범위가 결정됐을 때 사용하는 방식이다.
- 시작 위치(인덱스 탐색) 찾은 후 리프노드 간 링크를 통해 다음 리프노드를 찾아 스캔(인덱스 스캔)한다.
- 정순 또는 역순으로 정렬된 상태로 레코드를 가져온다.
- 느리다.
- 인덱스의 처음부터 끝까지 모두 읽는 방식이다.
- 느슨 하게 또는 듬성듬성 하게 인덱스를 탐색한다.
- 인덱스 레인지 스캔과 비슷하게 동작하지만, 중간마다 필요치 않은 인덱스 키 값을 스킵한다.
- 다음의 경우에 사용된다.
- GROUP BY
- MAX, MIN
- 집합 함수
- 두 개 이상의 칼럼으로 구성된 인덱스이다.
- 두번째 컬럼은 첫 번째 칼럼에 의존해서 정렬된다.
- 따라서 무엇을 첫번째로 할지, 순서가 중요하다.
- Rectangle Tree
- MBR: Minimum Bounding Rectangle
- Spatial Index (공간 인덱스) 라고 부르기도 한다.
- 어떤 도형을 감싸는 최소 크기의 사각형을 인덱스로 삼는다.
- 공간관련, 두 점 사이의 거리가 요구사항에 있는 경우에 쓸 수 있다.
- 예시: 현재 위치에서 가까운 카페 찾기
- 다만 R-Tree 인덱스를 쓸 바에는 MySQL 말고 다른 DBMS 를 사용하는게 낫다.
- 클러스터링은 여러개가 하나로 묶인것을 뜻한다.
- 클러스터링 인덱스는 레코드들이 PK 와 같은 정렬 방식으로 File에 저장되는 형태를 뜻한다.
- 이유는 PK가 비슷한 인근값들을 동시에 조회하는 경우가 확률상 높다고 생각하기 때문이다.
- 클러스터링 인덱스는 MyISAM 과 같은 다른 스토리지 엔진에서는 지원되지 않는다.
- InnoDB 에서만 클러스터링 인덱스가 지원된다.
- InnoDB 와 다른 스토리지 엔진의 차이를 면접 질문으로 물어본다면 클러스터링 인덱스에 대해 이야기해주자.
- PK 가 커지면, 다른 세컨더리 인덱스 전체도 크기가 커진다.
- 왜냐하면 클러스터링 테이블의 경우 모든 세컨더리 인덱스가 PK 값을 가지고 있기 때문이다.
- 인덱스가 커지면 같은 성능을 내기 위해 메모리또한 더 커져야하므로 InnoDB 테이블의 프라이머리 키는 신중하게 선택해야한다.
- 탐색보다는 "Unique" 제약 조건을 걸기 위해 사용된다.
- 왜냐하면 MySQL 에서 INDEX 없이 유니크 제약을 설정하는건 성능에 안좋기 때문이다.
- 유니크 인덱스 읽기
- 유니크 인덱스와 유니크하지 않은 인덱스 사이에 성능차이는 크지 않다.
- 둘다 비슷한 DISK IO 가 발생하기 때문이다.
- 유니크 인덱스 쓰기
- 유니크 인덱스는 쓰기성능이 더 나쁘다.
- 쓰기동작에서 중복인지 아닌지를 체크하기 위해 락이 걸리기 때문이다.