non - clustered index

음... 어제는 clustered index에 대해서 봤는데 인덱스 키 값에 따라 배열하는것으로 물리적인 데이터 값을 정렬하는것으로 이해하고 넘어갔다. 

오늘은 non - clustered index에 대해 보자. 이 내용은 테이블의 물리적 정렬 순서와는 별도의 구조를 갖는다. clustered index 처럼 인덱스 키값에 따라 정렬되지만, 테이블의 실제 데이터는 그 순서에 영향을 받지 않는다. 

정렬된 인덱스 키에 대한 쿼리가 수행할 때 non - clustered index는 정렬된 키와 각 키에 해당하는 데이터 행의 위치에 가리키는 포인터를 이용해 결과를 찾아간다. 

non - clustered index 의 구조에 대해 살펴보자. 좋은 참고 지표가 있어서 가져와 봤다 ! 

이 그림을 보면 인덱스 페이지 안에서 정렬된 인덱스는 존재하지만 실제 데이터 페이지에서는 데이터 값이 정렬되지 않은것을 볼 수 있다. 

사진 밑 블로그 내용을 가지고 와보면 데이터 페이지 번호 + 오프셋으로 데이터 페이지의 특정 행을 가리킬 수 있다고 한다. 

 

https://hudi.blog/db-clustered-and-non-clustered-index/

 

우선순위?

문득 clustered index 와 non-clustered index의 우선순위는 없나 고민하게 되었다. 

결과적으로 실행할 쿼리에 따라 다른데, 쿼리 옵티마이저가 결정한다.

DB의 경우에 쿼리 실행 계획을 수립하게 되는데 "이름" 에 대한 non-clustered index가 있다면 해당 디비에서 이 인덱스를 이용해서 검색을 하고 clustered index로 "주민등록번호" 가 있는 경우 "이름" 검색은 도움이 되지 않기 때문에 non-clustered index가 우선적으로 사용된다. 

non-clustered index 단독 사용? 

non-clustered index를 단독으로 사용하는 케이스는 잘 없다. non-clustered index가 데이터 페이지 번호 및 오프셋을 가지게 되면 데이터 페이지 위치가 바뀔 때마다 모든 인덱스 항목을 업데이트 해야 한다. (인덱스 페이지에서는 정렬이 되어 있을꺼니까... )

쓰면 좋은 케이스는 일단 테이블당 인덱스를 여러 개 생성할 수 있다는 특징을 고려해보면 기본 키가 아닌 특정 컬럼에 대해 빈번한 검색 쿼리가 이루어질 때 non-clustered index를 생성하여 검색 성능을 향상 시킬 수 있다. 

그래서 pk 즉, clustered index의 기본키 값을 가지고 있으면 데이터 페이지의 물리적 위치가 변경되어도 인덱스 항목을 업데이트할 필요가 없다. 

이부분에 대해 자세히 다뤄보겠다 ! 

예를 들면 non-cluster 인덱스로 부서ID 를 지정하고 clustered 인덱스로 직원 ID (PK) 저장했다고 가정하자. 

데이터 접근 과정

1. 사용자가 특정 부서 ID로 직원을 검색하는 쿼리를 실행한다. DB는 부서 ID에 대한 non-clustered 먼저 탐색한다. 

2. non-clustered 인덱스를 찾은 후에 직원 ID를 통해 DB에 clustered index를 사용해 실제 데이터 행에 접근한다. 

3. clustered 인덱스는 직원 ID에 따라 물리적으로 정렬된 데이터 행 위치를 관리한다. 

이렇게 하면 장점은 non-clustered 인덱스 안정성이 있다. 

  • 데이터가 추가되어도 clustered index 값은 변하지 않는다. 
  • non-clustered index 로 부서 id를 찾은다음에 cluster index 의 직원 id를 찾으므로써 데이터 행이 물리적으로 이동해도 non-clustered index를 재구성할 필요가 없다. 
  • 그렇지만 clustered-index 같은 경우 물리적인 재정렬을 수행해야 될 수 있다. 

그러면 궁금한게 생길 수 있다. clustered - index만 쓰는거랑 별 차이가 없는거 같은데..? 

clustered index를 쓰는건 한 테이블에는 단 하나의 클러스터링 인덱스만 존재할 수 있지만 다른 컬럼에 대한 검색 최적화는 제한적일 수 있다. 

non-clustered index 을 같이 쓰게 되면 다중 컬럼 검색하는데 최적화 할 수 있다는 장점이 있다. 

결론

clustered-index만 쓰는게 적합한 경우도 있지만 대부분 데이터베이스 환경에서 여러 쿼리, 데이터 접근 패턴이 존재하기 때문에 여러 요구사항을 만족하는 non-clustered index를 같이 사용하는것이 좋다. 

그리고 먼가 여기서 우리 프로젝트에서는 cluster index 와 non-cluster index를 어떻게 쓰고 있는지 궁금해졌다... ! 나중에 봐야겠다. (미션) 

 

next 오늘은 알고리즘을 풀어야 한다.

leetcode 방에서 한동안 안풀었더니 밀린 문제가 너무 많다. 한문제를 다뤄보고자 한다. 

오늘 다뤄볼 문제는  insert-delete-getrandom-o1 이 문제이다. 

이 문제 ArrayList를 이용했는데 O(n)이여서 안되더라.. HashSet을 이용해서 insert, remove 시 O(1) 안에 해결할 수 있다.