ไวยากรณ์ 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) จึงไม่จำเป็นต้องซ้ำกันในตาราง "uniquifier" จะถูกสร้างขึ้นโดยอัตโนมัติโดย 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)