기본 키이기도 한 클러스터형 인덱스를 생성하기위한 SQL Server 구문은 다음과 같습니다.
CREATE TABLE dbo.c
(
c1 INT NOT NULL,
c2 INT NOT NULL,
CONSTRAINT PK_c
PRIMARY KEY CLUSTERED (c1, c2)
);
"PK에서 명명 된 인덱스를 사용하게"위의 코드는 기본 키 색인의 이름이 "PK_c"가되도록합니다.
기본 키와 클러스터링 키가 동일한 열일 필요는 없습니다. 별도로 정의 할 수 있습니다. 위의 예에서 CLUSTERED
키워드를로 변경 NONCLUSTERED
한 다음 CREATE INDEX
구문을 사용하여 클러스터 된 인덱스를 추가하십시오 .
CREATE TABLE dbo.c
(
c1 INT,
c2 INT,
CONSTRAINT PK_c
PRIMARY KEY NONCLUSTERED (c1, c2)
);
CREATE CLUSTERED INDEX CX_c ON dbo.c (c2);
SQL Server에서 클러스터형 인덱스 는 테이블이며, 동일합니다. 클러스터형 인덱스는 테이블에 저장된 행의 논리적 순서를 정의합니다. 첫 번째 예에서 행은 c1
및 c2
열 값 순서로 저장됩니다 . 클러스터링 키도 기본 키로 정의되므로 c1
및 조합은 c2
테이블 전체에서 고유해야합니다.
두 번째 예에서 기본 키는 c1
및 c2
열로 구성 되지만 클러스터링 키는 c2
열입니다. 명령문 에서 UNIQUE
속성을 지정하지 않았으므로 CREATE INDEX
클러스터링 키 ( c2
)가 테이블에서 고유하지 않아도됩니다. "고유 화기"는 SQL Server에 의해 자동으로 생성되고 c2
열의 값에 추가되어 클러스터링 키를 생성합니다. 이 클러스터링 키는 이제 고유하기 때문에 테이블에서 작성된 다른 인덱스에서 행 ID로 사용됩니다.
클러스터링 키가 스토리지의 행 레이아웃을 제어 함을 증명하기 위해 문서화되지 않은 기능을 사용할 수 있습니다 fn_PhysLocCracker(%%PHYSLOC%%)
. 다음 코드는 행이 c2
열 순서대로 디스크에 배치되어 클러스터링 키로 정의 된 것을 보여줍니다 .
USE tempdb;
CREATE TABLE dbo.PKTest
(
c1 INT NOT NULL
, c2 INT NOT NULL
, c3 VARCHAR(256) NOT NULL
);
ALTER TABLE PKTest
ADD CONSTRAINT PK_PKTest
PRIMARY KEY NONCLUSTERED (c1, c2);
CREATE CLUSTERED INDEX CX_PKTest
ON dbo.PKTest(c2);
TRUNCATE TABLE dbo.PKTest;
INSERT INTO dbo.PKTest (c1, c2, c3)
SELECT TOP(25) o1.object_id / o2.object_id, o2.object_id, o1.name + '.' + o2.name
FROM sys.objects o1
, sys.objects o2
WHERE o1.object_id >0
and o2.object_id > 0;
SELECT plc.file_id
, plc.page_id
, plc.slot_id
, pk.*
FROM dbo.PKTest pk
CROSS APPLY fn_PhysLocCracker(%%PHYSLOC%%) plc;
내 tempdb 의 결과 는 다음과 같습니다.
위 이미지에서 처음 세 열은 fn_PhysLocCracker
함수 에서 출력 되어 디스크에서 행의 물리적 순서를 보여줍니다. 클러스터링 키인 slot_id
값으로 값이 잠금 단계를 증가시키는 것을 볼 수 있습니다 c2
. 기본 키 인덱스는 행을 다른 순서로 저장하는데, 이는 SQL Server가 기본 키 스캔 결과를 반환하도록하여 볼 수 있습니다.
SELECT pkt.c1
, pkt.c2
FROM dbo.PKTest pkt WITH (INDEX = PK_PKTest, FORCESCAN);
ORDER BY
기본 키 인덱스에 항목 순서를 표시하려고 시도했기 때문에 위의 문장에서 절을 사용하지 않았습니다 .
위 쿼리의 결과는 다음과 같습니다.
fn_PhysLocCracker
함수를 살펴보면 기본 키 인덱스의 물리적 순서를 볼 수 있습니다.
SELECT plc.file_id
, plc.page_id
, plc.slot_id
, pkt.c1
, pkt.c2
FROM dbo.PKTest pkt WITH (INDEX = PK_PKTest, FORCESCAN)
CROSS APPLY fn_PhysLocCracker(%%PHYSLOC%%) plc;
인덱스 자체에서 독점적으로 읽기 때문에 인덱스 외부의 열이 쿼리에서 참조되지 않으므로 %%PHYSLOC%%
값은 인덱스 자체의 페이지를 나타냅니다.
결과 :
create table c (c1 int not null primary key, c2 int)