MS SQL

MS SQL Clustered Index

darkturtle26 2018. 5. 8. 14:47


<< MS SQL Clustered Index >>


클러스터 인덱스 개념이 아리까리 해서 다시 정리 ㅇ.ㅇ


<< 요약 >>

1. 클러스터 인덱스 생성 시, 테이블은 클러스터 인덱스 칼럼으로 정렬되어 재구성됨 ( 별도 공간 차지 하지 않음 , 테이블 = 클러스터 인덱스 )

2. 논클러스터 인덱스는 클러스터 인덱스가 존재 하면, 클러스터 인덱스 칼럼 값을 갖고, 클러스터 인덱스가 없는 힙 테이블인 경우, 테이블 ROW 주소를 가짐

3. 논클러스터 인덱스는 클러스터 인덱스를 바라보는 구조라,  인덱스 REORG 작업 시, 클러스터 인덱스 먼저 REORG 재수행 필요함


1.


참조 :

http://wiki.gurubee.net/pages/viewpage.action?pageId=3902461


MSSQL 서버의 비클러스터형 인덱스 진화 과정

https://www.sqlshack.com/what-is-the-difference-between-clustered-and-non-clustered-indexes-in-sql-server

(전제) 클러스터형 인덱스 + 비클러스터형 인덱스 구성 

* ROWID = 데이터 행에 대한 포인터 = 행 로케이터 

* 인덱스 = 클러스터 인덱스가 있는 경우 --> 클러스터 인덱스 칼럼 값

               클러스터 인덱스가 없는 경우 --> 행 로케이터(행에 대한 포인터)


-. SQL SERVER 6.5 이전에는 좌측처럼 비클러스터형 인덱스가 클러스터형 인덱스 레코드가 직접 가리키는 ROWID 를 갖도록 하였다. 

    ( 즉, 비클러스터형 인덱스가 클러스터형 인덱스의 ROWID ( ROW 의 물리적 주소 정보) 를 가짐 

-. 인덱스 분할에 의해 클러스터형 인덱스 레코드 위치가 변경될 때마다 비클러스터형 인덱스

    (한 개 이상일수 있음)가 갖는 ROWID 정보를 모두 갱신해 주어야 함

   ( 하나의 클러스터형 인덱스 + 10개의 비클러스터형 인덱스 구성 시,

     하나의 클러스터형 인덱스의 ROWID 가 변경되면, 10개의 비클러스터형 인덱스의 ROWID 를 

     모두 변경해야함 )

-. DML 부하가 심하다고 느낀 MS는 SQL Server 7.0 부터 비클러스터형 인덱스가 rowid 

   대신 클러스터형 인덱스 키 값을 갖도록 구조를 변경

    ( 7.0 부터 비클러스터형 인덱스는 클러스터 인덱스의 rowid 대신에 

     클러스터형 인덱스의 인덱스 구성 칼럼 정보 자체를 갖도록 함)

-. 이제 키 값을 갱신하지 않는 한, 인덱스 분할 때문에 비클러스터형 인덱스를 갱싱할 필요가 없어진 것이다.

    ( 단순히, 클러스터 인덱스의 rowid 갱신에 영향을 받지 않게 되었다. 클러스터 인덱스이 

      구성 칼럼 값 자체를 가지고 있어

      단. 클러스터 인덱스의 구성 칼럼 값 자체가 변경되면, 비클러스터 인덱스의 

      모든 클러스터 인덱스 구성 칼럼 값 정보를 업데이트 해야함 )

-. DML 부하가 줄어든 대신, 디클러스터형 인덱스를 이용할 때 이전 보다 더 많은 I/O가 발생하는 

   부작용을 떠안게 되었다.

    ( rowid 는 물리적 주소 정보라 고정사이즈나, 인덱스 구성 칼럼 값은 , 인덱스 구성 칼럼을 어떻게 

     구성 하냐에 따라서, 비클러스터형 인덱스가 가져야할 데이타량 정보가 증가됨 )

   우측 그림처럼 비클러스터형 인덱스에서 읽히는 레코드마다 건건이 클러스터형 인덱스를 

   수직탐색 반복하기 때문이다.

   당연히 클러스터형 인덱스 높이가 증가할수록 블록 I/O 도 증가한다.


2.

참조 :

https://msdn.microsoft.com/ko-kr/library/ms190457(v=sql.120).aspx


3. 

참조 : 

https://www.sqlshack.com/what-is-the-difference-between-clustered-and-non-clustered-indexes-in-sql-server/


It is important to mention here that inside the table the data will be sorted by a clustered index. 


Conclusion

From the discussion we find following differences between clustered and non-clustered indexes.

1. There can be only one clustered index per table. However, you can create multiple non-clustered indexes on a single table.

2. Clustered indexes only sort tables. Therefore, they do not consume extra storage. Non-clustered indexes are stored in a separate place from the actual table claiming more storage space.

3. Clustered indexes are faster than non-clustered indexes since they don’t involve any extra lookup step.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 CREATE  TABLE  student 
 (  id  INT   PRIMARY  KEY ,  
     name  VARCHAR ( 50 )   NOT   NULL ,       gender  VARCHAR ( 50 )   NOT   NULL ,       DOB  datetime  NOT   NULL , 
     total_score  INT   NOT   NULL ,       city  VARCHAR ( 50 )   NOT   NULL    ) 
GO
EXECUTE  sp_helpindex  student 
GO
 INSERT  INTO  student 
 VALUES   
 ( 6 ,   'Kate' ,   'Female' ,   GETDATE() ,   500 ,   'Liverpool' ) ,  
 ( 2 ,   'Jon' ,   'Male' ,   GETDATE() ,   545 ,   'Manchester' ) , 
 ( 9 ,   'Wise' ,   'Male' ,   GETDATE() ,   499 ,   'Manchester' ) ,  
 ( 3 ,   'Sara' ,   'Female' ,   GETDATE() ,   600 ,   'Leeds' ) ,  
 ( 1 ,   'Jolly' ,   'Female' ,   GETDATE() ,   500 ,   'London' ) , 
 ( 4 ,   'Laura' ,   'Female' ,   GETDATE() ,   400 ,   'Liverpool' ) , 
 ( 7 ,   'Joseph' ,   'Male' ,   GETDATE() ,   643 ,   'London' ) ,   
 ( 5 ,   'Alan' ,   'Male' ,   GETDATE() ,   500 ,   'London' ) ,  
 ( 8 ,   'Mice' ,   'Male' ,   GETDATE() ,   543 ,   'Liverpool' ) , 
 ( 10 ,   'Elis' ,   'Female' ,   GETDATE() ,   400 ,   'Leeds' ) ; 
 GO 
 SELECT * FROM student
 GO
 
cs


>>클러스터 인덱스 생성 후,  테이블  조회 시, 클러스터 인덱스 칼럼 ID 값으로 정렬 결과를 Return 받음 <<