인덱스?
인덱스 또한 자료구조이다. 다만 인덱스 설정을 해놓은 컬럼을 정렬해 놓은 자료구조라는 점이 특별한 것이다. 국어사전에서 자음(ㄱ,ㄴ)을 기준으로 책 옆에 목차가 적혀있는 것을 봤을 텐데, DB에서는 우리가 설정하는 컬럼이 국어사전의 자음처럼 목차로 만들어진다.
읽기 작업에서만 인덱스가 중요하다고 생각할수 있는데 수정, 삭제 작업에서도 인덱스가 중요하다. 당연히 수정, 삭제 하기전에 대상 데이터를 찾아야하니 말이다.
인덱스는 대부분 써야하는게 맞다. 다만 잘못쓰면 여러 성능저하를 주기도 하고 데이터의 종류, 구조가 바뀌면 인덱스 또한 바꿔줘야하니 그것은 주의하자.
그럼 인덱스를 어떤 방식으로 설정하지?
설정 기준
1. 첫째로는 query에 제일 많이 활용되는 데이터여야 한다.
“where 조건에 자주쓰이는 값” 당연하게도 어떤 컬럼이 검색에 제일 많이 쓰이는지에 따라 인덱스 설정이 달라진다. 예를 들어 이름과 나이 컬럼이 있다고 했을 때, 이름으로는 검색을 10번하는데 나이로는 검색을 1번 한다면 당연히 이름으로 인덱스를 설정해야한다.
2. 둘째로는 유니크한 값이 많을수록 인덱스 설정.
카디널리티(Cardinality)라고들 하는데 단어가 와닫지 않아서 머리속에 넣기가 힘들다. 카디널리티대신 컬럼이 얼마나 다양한 값으로 구성되는지 정도라고 생각하자.
예를 들어 파악하면 편하다. 성별 컬럼과 이름 컬럼을 비교해보자. 성별은 남,여 2가지인데 비해 이름은 수없이 종류가 다양하다. 성별에 인덱스를 설정해두면 값의 종류가 단 2가지이므로 인덱스를 설정해둔다고 할지라도 50%밖에 검색 범위가 줄어들지 않는다. 반면에 이름은 자음으로만 따져봐도 19개이다. 검색 이름이 “김아무개”(ㄱ 으로 시작)라고 한다면 [ㄱ,ㄴ,ㄷ,ㄹ ~ ㅉ] 중에 [ㄴ,ㄷ,ㄹ ~ ㅉ] 이 걸러진다. 18/19 94퍼센트가 검색 범위에서 제거된 것이다.
“카디널리티”, “선택도”, “중복도” 이 3가지가 인덱스 설정 유의사항에 많이 나오는 내용인데 3가지가 비슷한 이야기를 하고 있는 것이라서 값의 유니크성만 생각하도 된다고 본다.
나머지 팁
- 인덱스는 DB 메모리에 저장되므로 이용하지 않는다면 바로바로 제거하자.
- 복합 인덱스 설정시 첫번째 인덱스는 유니크성이 높은 콜럼으로 설정한다.
- (인덱스만을 위한 주의사항이 아니지만) or 연산자를 막쓰다보면 거의 전체 테이플을 검색하는 일이 발생할수도 있으니 or
연산은 주의하길.
인덱스 자료구조
글 서두에 인덱스는 자료구조라고 하였다. 어떤 자료구조를 이용하는지 대략적으로 알아보고 넘어가자. (개인적으로는 기술면접에서 이 질문을 받았던 적이있었다.)
대부분의 기본 인덱스 자료구조는 B-Tree이다.
빠른 성능을 위해서 인덱스가 존재한다고 했는데 왜 탐색시간이 가장 빠른 Hash를 쓰지않고 B-Tree인거냐고 물을 수 있다. 하지만 좀더 데이터베이스 활용 방식을 생각해보면 query를 할때 우리는 특정 값으로 동일 검색만을 하는 것이 아니라 범위 검색을 하는일도 그만큼 많다는 것을 알 수 있다. 심지어 equal(=) 검색을 하기전에 범위 검색을 먼저 진행해서 equal 검색을 할 데이터를 받아와야만 하는 경우가 대부분이다. 대부분의 어플, 웹사이트 메인화면이 그렇지 않나.
그리고 다른 자료구조 많은데 왜 B-Tree인지 물을수 있는데 그건 나보다 설명을 잘하는 분들이 많으니 그들의 글을 참고하자. 데이터베이스 인덱스는 왜 ‘B-Tree’를 선택하였는가 이분이 참 잘썼다.