Sql Server Index
#
Sql Server Page 구성도데이터베이스에서 데이터 파일에 할당되는 디스크공간은 논리적인 페이지로 나뉘면서 연속적인 숫자가 페이지에 매겨진다.
책이 page로 구성되어 있는 것처럼 SQL 서버도 Page로 구성되어 있으며 크기는 8KB 이다.
SQL서버의 가장 기본적인 단위이며, 실제로 SQL서버에 데이터의 접근시에는 페이지 단위로 접근합니다.
페이지는 대부분 Data로 구성되어 있지만 일부 페이지는 인덱스(데이터 위치), 텍스트/이미지, 등등으로도 구성되어 있다.
각 페이지는 96바이트의 헤더로 구성되어 있으며, 헤더는 페이지에 대한 시스템 정보를 저장한다.
#
ExtentsSql Server의 Extent는 공간 관리의 기본 단위이며, 하나의 Extent는 연속하는 8페이지이다.
일반적으로 신규 테이블이나 인덱스는 Mixed extent의 페이지를 할당한다. (효율을 위해서)
이후 해당 테이블이나 인덱스가 8페이지로 증가하면 후속 할당을 위해서 uniform extent를 사용하도록 전환된다.
(SQL Server 2016부터 모든 할당의 기본값은 uniform extent를 사용)
type | content |
---|---|
mixed extent | 최대 8개의 다른 개체(테이블이나 인덱스등)이 공유된다. (페이지 단위) |
uniform extent | 단일 개체가 모든 8페이지를 소유하며, 전체 페이지는 소유개체만 사용가능. |
#
PFS 페이지PFS(Page Free Spece) 페이지는 Page 할당여부 및 빈 공간의 양을 1바이트로 표시한다.
PFS 페이지는 8088개의 페이지(64MB)의 빈공간을 추적하며, 8088개 페이지 이후에는 새로운 PFS 페이지가 생성된다.
페이지 상태 비어 있음 1 ~ 50% 채워짐 51 ~ 80% 채워짐 81 ~ 95% 채워짐 96 ~ 100% 채워짐
#
Extent 할당 및 빈 공간 관리#
빈 공간 추적PFS(Page Free Space) 페이지는 개별 페이지의 할당 여부 및 각 페이지에 있는 빈 공간의 양과 같은 페이지의 할당 상태를 기록하고. PFS는 각 페이지에 1바이트를 사용하여 페이지의 할당 여부를 기록하고 할당된 경우 페이지의 상태를 비어 있음, 1~50% 채워짐, 51~80% 채워짐, 81~95% 채워짐 또는 96~100% 채워짐으로 기록을 진행한다.
개체에 익스텐트가 할당된 후에는 SQL Server 데이터베이스 엔진에서 PFS 페이지를 사용하여 익스텐트의 할당된 페이지 또는 빈 페이지를 기록합니다. 이 정보는 SQL Server 데이터베이스 엔진에서 새 페이지를 할당해야 할 때 사용된다.
추적되는 각 추가 범위에 대한 새 PFS, GAM 또는 SGAM 페이지가 데이터 파일에 추가된다.
따라서 첫 번째 PFS 페이지 뒤에 8,088페이지의 새 PFS 페이지가 있고, 그다음에는 8,088페이지 간격으로 추가 PFS 페이지가 나온다.
밑에 그림을 페이지1할당 후 PFS 페이지로 페이지가 관리되고, 그 뒤에 GAM 페이지 뒤에 64,000개 익스텐트의 새 GAM 페이지가 있고, 그다음에 나오는 64,000개 익스텐트를 추적한다. (이후 64,000개 익스텐트 간격으로 시퀀스가 계속된다)
#
Sql Server Index인덱스가 없을경우 아래 그림처럼 저장된다.
#
Clusterd Index클러스터 인덱스 구조에서 인덱스 페이지의 루트 노드 및 중간 노드들은 인덱스 행을 포함하게 구성되어 있다.
리프 노드들은 기본 테이블의 데이터 페이지로 구성되어 있으며 기본 테이블 데이터 페이지의 데이터 값들은 인덱스 값을 기준으로 정렬된다.
인덱스 페이지를 통해서 인덱스를 통한 데이터 검색을 할 경우 해당하는 데이터 페이지를 찾아갈 수 있다.
클러스터 인덱스를 생성할경우 아래 그림처럼 생성이 된다.
#
Non Clusterd Index인덱스 페이지의 루트 페이지에는 클러스터와 동일하게 인덱스키와 리프페이지의 페이지 번호로 구성된다.
하지만 클러스터 인덱스와는 다르게 인덱스 페이지의 리프 페이지는 데이터 페이지가 아닌 데이터 페이지의 포인터로
구성된다.(실제로는 페이지 번호 + 행번호(RID)로 구성)
비 클러스터 인덱스에서 조회를 진행한다면
- 첫번째로 인덱스의 루트페이지를 접근해서 찾는 값이 어떤 리프 페이지에 있는지 확인
- 리프 페이지로 이동 후에 페이지의 내부 행들을 검색해서 데이터의 포인터 정보에 접근
- 포인터 정보를 기반으로 데이터 페이지에 접근
검색 과정에서 총 3개의 페이지(루트 페이지 + 리프 페이지 + 데이터 페이지)를 참조하게 됨.