인덱스 요약
데이터를 빠르게 검색할 수 있게 해주는 객체로, 컬럼을 정렬한 후 데이터를 빠르게 찾을 수 있도록 도와주는 역할을 한다. 책으로 비유하자면 색인을 의미한다.
그렇다면 인덱스를 생성하면 무조건 데이터를 빠르게 검색할 수 있을까? 인덱스를 무작정 생성하는 것은 좋은 방법이 아니다. 인덱스 생성시 디스크 공간이 필요하고, 인덱스를 가진 테이블에 DML(insert, delete, update) 작업을 할 경우 더 많은 비용과 시간이 필요하기 때문이다. 그래서 인덱스를 생성할 때에는 테이블의 의도를 정확하게 파악한 후 상황에 맞게 적절한 컬럼으로 Clustered Index
와 Non Clustered Index
를 구성해야 한다.
클러스터 인덱스
클러스터 인덱스(Clustered Index)의 사전적인 의미는 군집화 된 인덱스를 말한다. 책으로 비유하자면 페이지를 알고 있어 바로 해당 페이지를 펼치는 것이라고 말할 수 있다. 데이터가 테이블에 물리적으로 저장 되는 순서를 정의한다. 즉, 특정 컬럼을 기준으로 데이터들을 정렬시킨다.
위의 사진에서는 ID값을 기준으로 데이터들이 정렬되어있는 것을 확인할 수 있다. 테이블 데이터는 오직 한 가지의 방법으로만 정렬되므로 테이블 당 하나의 클러스터 형 인덱스만 존재할 수 있다. (= 정렬 기준으로 오직 하나의 컬럼만을 선택할 수 있다.)
PK 제약조건은 클러스터 된 인덱스를 자동으로 생성하므로 데이터가 자동으로 정렬된다. 만일 PK를 설정하지 않은 테이블에 무작위로 데이터를 insert하고, 조회했다면 순서가 뒤죽박죽인 데이터를 볼 수 있다.
이상태에서 ID의 값이 2인 사람의 데이터를 추가해본다.
중간에 새로운 데이터가 삽입된다면 사진과 같이 이후의 모든 컬럼을 한 칸씩 이동시켜줘야 한다. 참고로 pk 값으로 자동 생성되는 것과 별개로 설정을 통해 테이블내에서 원하는대로 생성할 수 있다.
클러스터 인덱스는 트리로 저장되어, Root 페이지와 Leaf 페이지로 구성된다. Root 페이지는 Leaf 페이지의 주소로 구성되어 있으며, Leaf 페이지는 실제 데이터 페이지로 구성된다.(= 테이블 자체가 인덱스이다.) 데이터 검색 순서는 루트페이지에서 리프페이지(데이터 페이지)로 향한다.
어떤 경우에 생성할까?
- 테이블 데이터가 자주 업데이트 되지 않는 경우
- MAX, MIN, COUNT 등의 쿼리로 범위 또는 Group By 등의 조회를 하는 경우
- 항상 정렬 된 방식으로 데이터를 반환해야 하는 경우
- 테이블은 정렬되어 있기 때문에 ORDER BY 절을 활용해 모든 테이블 데이터를 스캔하지 않고 원하는 데이터를 조회할 수 있다.
- 읽기(SELECT) 작업이 월등히 많은 경우
넌 클러스터 인덱스
넌 클러스터 인덱스(NonClustered Index)의 사전적인 의미는 군집화되어 있지 않은 인덱스를 말한다. 책에 비유하자면 목차에서 찾고자 하는 내용의 페이지를 찾고 그 페이지로 이동하는 것이라고 볼 수 있다. 물리적으로 데이터를 정렬하지 않은 상태로 데이터 페이지가 구성된다.
- 테이블 데이터와 함께 테이블에 저장되는 것이 아닌 별도의 장소에 저장된다.
- 인덱스 페이지만을 위한 추가 저장공간이 필요하다.
- 하나의 테이블에 여러개의 인덱스를 설정할 수 있다. (남용하면, 시스템의 성능을 떨어뜨린다)
- 데이터의 행에 독립적이며, 인덱스 키 값과 데이터 행을 가리키는 포인터가 존재한다.
데이터 검색 순서는 루트페이지 > 리프페이지 > 데이터 페이지(Heap page)로 이동한다.
인덱스 페이지의 리프 페이지에 인덱스로 구성한 열을 정렬한 후 위치 포인터(RID)를 생성한다. (= 인덱스 자체의 리프 페이지는 데이터가아닌, 데이터가 위치하는 포인터다)
RID란?
파일그룹번호-데이터페이지번호-데이터페이지오프셋으로 구성되는 포인팅 정보를 말한다.
어떤 경우에 생성할까?
- WHERE 절이나 JOIN 절과 같이 조건문을 활용하여 테이블을 필터링 하고자 할 때
- 데이터가 자주 업데이트 될 때
- 특정 컬럼이 쿼리에서 자주 사용될 때
클러스터 인덱스 vs 논 클러스터 인덱스
기준 | 클러스터 인덱스 | 논 클러스터 인덱스 |
조회 속도 | 빠르다 | 느리다 |
사용 메모리 | 적다 | 많다 |
인덱스 | 인덱스가 주요 데이터 | 인덱스가 데이터의 사본(copy) |
개수 | 한 테이블에 한 개 | 한 테이블에 여러 개(최대 약 250개) |
리프 노드 | 리프 노드 자체가 데이터 | 리프 노드는 데이터가 저장되는 위치 |
저장값 | 데이터를 저장한 블록의 포인터 | 값과 데이터의 위치를 가리키는 포인터 |
정렬 | 인덱스 순서와 물리적 순서가 일치 | 인덱스 순서와 물리적 순서가 불일치 |
https://gwang920.github.io/database/clusterednonclustered/
https://junghn.tistory.com/entry/DB-%ED%81%B4%EB%9F%AC%EC%8A%A4%ED%84%B0-%EC%9D%B8%EB%8D%B1%EC%8A%A4%EC%99%80-%EB%84%8C%ED%81%B4%EB%9F%AC%EC%8A%A4%ED%84%B0-%EC%9D%B8%EB%8D%B1%EC%8A%A4-%EA%B0%9C%EB%85%90-%EC%B4%9D%EC%A0%95%EB%A6%AC
https://velog.io/@winters0727/클러스터-인덱스-vs-비-클러스터-인덱스
https://velog.io/@sweet_sumin/클러스터드-인덱스-Clustered-Index-넌-클러스터드-인덱스-Non-Clustered-Index
'Backend' 카테고리의 다른 글
[DB] Gap Lock, Record Lock, Next Key Lock (0) | 2024.03.04 |
---|---|
[DB] ERD란? ERD의 정의와 특징 (0) | 2024.02.23 |
[DB] RDBMS란? RDBMS에서 지원하는 ACID (1) | 2024.02.14 |