클러스터드 인덱스 (Clustered Index), 넌 클러스터드 인덱스 (Non Clustered Index)

유수민·2022년 7월 11일
6

지식창고

목록 보기
36/64

📌인덱스

인덱스는 데이터 레코드를 빠르게 접근하기 위해서 <키, 포인터>쌍으로 구성되는 데이터 구조이다. 테이블에 데이터가 저장되는데, 특정한 PK값을 가지는 데이터를 찾기 위해서 매번 접근하는 것은 비효율적이다. PK값과 해당하는 데이터 row의 주소를 자료구조로 묶어서 저장하는 것이 인덱스이다. 따라서, 인덱스는 DB의 테이블에 데이터가 많을 때, 검색 속도를 향상시켜주기위해 사용하는 객체이다. 컬럼을 정렬한 후에 데이터를 빠르게 찾을 수 있도록 도와주는 역할을 한다. 즉, 인덱스의 가장 큰 목적은 대용량 데이터 조회 시 select문의 조회 속도를 향상시키는 것이다. 인덱스로 설정되지 않은 컬럼의 조회는 Full Scan(Table Scan)수행하기 때문에 속도 저하를 가져온다 .

하지만, 인덱스를 생성하면 무조건 데이터를 빠르게 검색할 수 있을까? 아니다. 인덱스를 무작정 생성한다고 좋은 방법은 아니다. 인덱스를 생성하면 인덱스를 위한 디스크 공간이 필요하고, 인덱스를 가진 테이블에 DML 작업을 할 경우 더 많은 비용과 시간이 필요하다. 때문에 인덱스를 생성 시 해당 테이블의 의도를 정확하게 파악한 후에 상황에 맞게 적절한 칼럼으로 Clustered Index와 Non Clustered Index를 구성해야 한다.

DML(Data Manipulation Language)

데이터를 조작하는 명령어 ex) INSERT, DELETE, UPDATE

책에 비유하자면,

  • 클러스터 인덱스는 페이지를 알기 때문에 바로 그 페이지를 펴는 것
  • 넌 클러스터 인덱스는 뒤에 목차에서 찾고자 하는 내용의 페이지를 찾고 그 페이지로 이동하는 것.
  • 테이블 스캔은 처음부터 한 장씩 넘기면서 내용을 찾는 것

📖클러스터 인덱스(Clustered Index)

출처) https://gwang920.github.io/database/clusterednonclustered/

  • Clustered Index를 구성하기 위해서 행 데이터를 해당 열로 정렬한 후에, 루트 페이지를 만들게 된다. (물리적으로 행을 재배열)
  • Clustered Index는 트리로 저장되어, Root페이지와 Leaf페이지로 구성된다. 또한 Root페이지는 Leaf페이지의 주소로 구성하고, Leaf페이지는 실제 데이터 페이지로 구성된다. 따로 추가적인 저장소에 인덱스 페이지를 만들지 않는다.
  • 테이블당 단 하나의 Clustered Index만 존재할 수 있다.
  • 클러스터드 인덱스 순서로 레코드들이 하드디스크에 저장된다. 클러스터드 인덱스를 따로 지정하지 않으면, 기본 키(primary key)가 클러스터드 인덱스가 된다. 즉, 테이블 생성 시 Primary Key(PK)를 지정하면, 그 칼럼은 자동으로 Clustered Index가 만들어진다.
    → 만약 Clustered Index를 따로 지정하고 싶으면, 설정을 통해 테이블내에서 원하는 컬럼으로 Clustered Index로 생성할 수 있다.
  • 데이터 입력, 수정, 삭제 시 항상 정렬 상태를 유지한다.
  • Clustered Index는 물리적으로 정렬되어 있어 검색 속도가 Non-Clustered Index 보다 더 빠르다. 하지만 데이터의 입력. 수정, 삭제는 느리다.
  • 🌟데이터 검색 순서 : 루트페이지 > 리프페이지(데이터 페이지)

📚어떤 경우에 생성해야할까?

  • 테이블 데이터가 자주 업데이트 되지 않는 경우
  • MAX, MIN, COUNT등의 쿼리로 범위 또는 Group By 등의 조회를 하는 경우
  • 항상 정렬 된 방식으로 데이터를 반환해야하는 경우
    • 테이블은 정렬되어있기 때문에 ORDER BY 절을 활용해 모든 테이블 데이터를 스캔하지 않고 원하는 데이터를 조회할 수 있다.
  • 읽기 작업이 월등히 많은 경우, 이때 매우 빠르다.

📚단점

  • 리프 페이지가 모두 차있는데 새로운 데이터가 추가될때 페이지 분할이 일어난다.
    → 인덱스는 Balancing - Tree구조이기 때문에 기본적으로 모두 같은 크기의 페이지를 유지한다. 그래서 새로운 데이터가 추가되면 새로운 데이터가 추가 될 테이블의 기존 데이터 절반이 새로운 페이지로 이동한 후에 새로운 행이 추가된다. 이와 같이, 인덱스를 생성/수정/삭제할 때 페이지 분할이 일어나며 데이터 페이지 전체를 다시 정렬해야 하기 때문에 느려진다.
  • 항상 순서를 유지해야 한다.

📖넌 클러스터 인덱스(Non Clustered Index)

출처) https://gwang920.github.io/database/clusterednonclustered/

  • 레코드의 원본은 정렬되지 않고, 인덱스 페이지만 정렬된다. 즉, Non-Clustered Index는 데이터 페이지를 건드리지 않고, 별도의 장소에 인덱스 페이지를 생성
    한다.
  • 인덱스 페이지의 리프 페이지에 Index로 구성한 열을 정렬한 후 위치 포인터(RID)를 생성한다. 즉, Non-Clustered Index의 인덱스 페이지(리프 페이지)는 키값과 데이터가 위치하는 포인터(RID)로 구성된다.

    포인터(RID): '파일그룹번호+데이터페이지 번호 + 페이지 내의 로우 번호'으로 구성되는 포인팅 정보.

  • 인덱스를 생성할 때 데이터 페이지는 그냥 둔 상태에서 별도의 인덱스 페이지를 따로 만들기 때문에 용량을 더 차지한다.
  • 테이블당 약 240개의 Non Clustered Index를 만들 수 있다.
  • 클러스터형보다 검색 속도는 더 느리지만 데이터의 입력, 수정, 삭제는 더 빠르다.
    → 클러스터드 인덱스보다 페이지 분할이 적게 일어난다.
  • 🌟데이터 검색 순서 : 루트페이지 > 리프페이지 > 데이터 페이지 (Heap page)
  • 리프페이지가 모두 차 있어도 페이지 분할은 일어나지 않는다.

📚어떤 경우에 생성해야할까?

  • where절이나 Join 절과 같이 조건문을 활용하여 테이블을 필터링 하고자 할 경우
  • 데이터가 자주 업데이트 될 경우
  • 특정 컬럼이 쿼리에서 자주 사용 될 경우

📚단점

  • 클러스터 인덱스는 테이블 정렬만 하면 되니 추가적인 저장공간이 필요없지만, 넌클러스터 인덱스는 인덱스 페이지만을 위한 추가 저장공간이 필요하다.
    → 데이터 삽입시 넌클러스터 인덱스는 별도의 공간에 인덱스를 생성해야하기 때문에 추가작업이 필요하다.
  • 넌클러스터 인덱스는 데이터 접근 속도가 클러스터 인덱스보다 상대적으로 느리다.
  • 인덱스 조회 시 비용이 많이 발생한다. (거쳐야 하는 단계가 많다)
    → 검색하고자하는 데이터의 키 값을 루트 페이지에서 비교하여 리프 페이지 번호를 찾고, 리프 페이지에서 RID 정보로 실제 데이터의 위치로 이동
  • 클러스터 인덱스의 변경이 발생할 때 그에 상응하는 업데이트가 발생한다.

📖비교

profile
배우는 것이 즐겁다!

2개의 댓글

comment-user-thumbnail
2023년 1월 2일

안녕하세요 인덱스에 대해 자세히 알아보는 공부를 하다가 보게된 글인데 잘봤습니다.
질문이 하나 있는데 클러스터드 인덱스는 따로 인덱스를 만들지 않는다고 하셨는데
그럼 루트페이지는 인덱스 페이지라고 부르지 않는건가요?
제가 알기로는 루트레벨에 인덱스페이지가 있으면 루트 페이지라고 부르는걸로 알았는데 너무 헷갈리네요 ㅠㅠ

1개의 답글