인덱스가 무엇인지, B-Tree Index, Hash Index 등에 대해 알고있다는 가정하에 작성
인덱스는 '인덱스가 검색 범위를 제한시켜주기 때문에' 빠르게 데이터를 검색할 수 있게 해준다.
인덱스는 항상 정렬이 되있기 때문에 라고 생각할 수 있지만, 그건 특정 인덱스에 한정된 이야기다.
검색범위를 제한해주는 방법은 어떤 인덱스를 사용하느냐에 따라 달라진다.
B-Tree의 경우 대부분의 DBMS에서 기본적으로 사용한다. 위에서 언급한대로 항상 정렬된 상태를 유지하기 때문에 범위검색을 할때 유용하기 때문이다.
해시 인덱스는 메모리기반의 테이블에 주로 사용된다. 디스크 기반 대용량 테이블용으로는 적합하지 않다. 왜냐하면 정렬된 결과를 가져올 수 없기 때문이다.
버킷은 링크드리스트를 저장하는 배열이라고 생각하면 된다.
버킷의 위치를 정한다는 말은 데이터를 해싱해서 적절한 배열 인덱스를 구하는 것이다.
다른 자료구조도 많은데(레드 블랙 트리 등), B-Tree를 쓰는 이유
B-Tree 인덱스의 다중 컬럼 인덱스는 컬럼 순서가 매우 중요하다. 순서에 따라 해당 인덱스를 활용하지 못 할 수도 있기 때문이다.
반드시 왼쪽에 있는 컬럼이 사용되어야 그 오른쪽의 컬럼도 사용될 수 있다.
그럼 어떤 기준으로 순서를 정하는게 좋을까? (단일 컬럼 인덱스에도 적용되는 해당되는 이야기)
카디널리티는 유니크한 값의 개수를 말한다.
예를 들어 100명 중 A로 시작하는 사람은 10명, 전체 남자는 70명이다.
그리고 A로 시작하는 남자는 5명이다.
select NAME, GENDER from EMPLOYEES where NAME like 'A%' and GENDER='male'
선택도란 얼마나 값을 잘 가져오냐를 말하는데, 1이면 유니크하다는 의미다.
20~25% 를 넘어서면 그 인덱스를 사용하지 않는게 좋다고 한다.
이전 예제와 차이는 여기선 이름을 오름차순으로 가져온다는 것이다.
select NAME, GENDER where GENDER='male' order by NAME LIMIT 10
기수성 예와 반대로 (GENDER, NAME) 인덱스를 더 효율적으로 사용한다.
SELECT NAME, GENDER
이므로 커버링 인덱스가 사용되어 효율적이라고 볼 수 있다.그러나 (GENDER, NAME) 이 인덱스가 얼마나 활용될 수 있을지 고민해봐야 한다.
이 인덱스는 이름순으로 특정 성별을 찾는 아주 특정한 케이스에만 활용될 수 있다.
인덱스는 곧 디스크 용량을 차지하고 메모리를 차지하기 때문에 크기가 큰 테이블인데 활용도가 떨어지면 굳이 이 인덱스(GENDER, NAME)을 쓸 필요는 없을 것 같다.
Aaaa - Male
Aaab - Male
Aaac - Male
...
이런 식으로 성별이 연달아 남자만 나오는 경우. 10건만 읽으면 된다.
이름순 상위 50명이 모두 여자인 경우.
Aaaa - Female
Aaab - Female
Aaac - Female
...
옵티마이저가 인덱스를 정방향으로 읽을지 역방향으로 읽을지 결정할 수 있다.
MySQL8 버전은 내림차순 인덱스도 지원을 해서 (NAME ASC, GENDER DESC) 같은 인덱스를 사용할 수 있다.