SQL Server เทียบเท่ากับ Oracle USING clause


9

มี SQL Server 2008 เทียบเท่ากับ USING INDEX clause ใน Oracle หรือไม่? เฉพาะสำหรับการสร้าง:

CREATE TABLE c(c1 INT, c2 INT);
CREATE INDEX ci ON c (c1, c2);
ALTER TABLE c ADD CONSTRAINT cpk PRIMARY KEY (c1) USING INDEX ci;

ในเอกสารเซิร์ฟเวอร์ SQL ในดัชนีที่ไม่ซ้ำจะระบุ (เน้นเพิ่ม):

มีการใช้ดัชนีที่ไม่ซ้ำกันในวิธีต่อไปนี้:

คีย์หลักหรือข้อ จำกัด ที่ไม่ซ้ำกัน

เมื่อคุณสร้างข้อ จำกัด คีย์หลักดัชนีคลัสเตอร์ที่ไม่ซ้ำกันในคอลัมน์หรือคอลัมน์ที่ถูกสร้างขึ้นโดยอัตโนมัติหากดัชนีคลัสเตอร์บนโต๊ะไม่ได้อยู่แล้วและคุณไม่ได้ระบุดัชนี nonclustered ที่ไม่ซ้ำกัน คอลัมน์คีย์หลักไม่อนุญาตให้มีค่า NULL

ซึ่งดูเหมือนจะบอกเป็นนัยว่ามีวิธีระบุดัชนีที่ควรใช้สำหรับคีย์หลัก


เพียงกำหนด PK พร้อมกับตาราง create table c (c1 int not null primary key, c2 int)
a_horse_with_no_name

มันคือ "การสร้าง PK ใช้ดัชนีที่มีชื่อ" ซึ่งฉันสนใจ
nik

ไม่มีทางที่จะทำเช่นนั้นได้ คีย์หลักคือข้อ จำกัด และดัชนี ในสิ่งที่คุณให้คีย์หลักโดยค่าเริ่มต้นจะเป็นดัชนีคลัสเตอร์ที่ไม่ซ้ำ ซึ่งจะทำให้ดัชนีที่กำหนดอื่น ๆ ซ้ำกันจนกว่าคุณจะรวมทั้ง c1 และ c2 ในส่วนคำสั่ง where
Aaron

คำตอบ:


7

มี SQL Server 2008 เทียบเท่ากับ USING INDEX clause ใน Oracle หรือไม่?

ไม่เมื่อคุณสร้างคีย์หลักหรือข้อ จำกัด ที่ไม่ซ้ำกันใน SQL Server ดัชนีเฉพาะเพื่อสนับสนุนข้อ จำกัด นั้นจะถูกสร้างขึ้นโดยอัตโนมัติด้วยคีย์เดียวกัน

ซึ่งดูเหมือนจะบอกเป็นนัยว่ามีวิธีระบุดัชนีที่ควรใช้สำหรับคีย์หลัก

ไม่เอกสารคู่มือพยายามอธิบายว่าจะสร้างดัชนีการสนับสนุนอัตโนมัติแบบคลัสเตอร์หรือแบบไม่รวมกลุ่มหากคุณไม่ได้ระบุไว้ ฉันเห็นด้วยอย่างสับสน

เมื่อต้องการเพิ่มข้อ จำกัด คีย์หลักให้กับตารางที่มีอยู่โดยไม่แสดงค่ากำหนดดัชนีสนับสนุนจะถูกทำคลัสเตอร์หากไม่มีดัชนีคลัสเตอร์ที่มีอยู่แล้วในตาราง ดัชนีที่สนับสนุนจะถูกสร้างขึ้นเป็นnonclusteredหากมีดัชนีคลัสเตอร์อยู่แล้ว

คุณโดยเฉพาะสามารถขอคลัสเตอร์หรือ nonclustered คีย์หลักโดยใช้: หรือPRIMARY KEY CLUSTEREDPRIMARY KEY NONCLUSTERED

ในความเป็นธรรมเอกสารมีความชัดเจนมากในเรื่องที่:

table_constraint (Transact-SQL)


5

ไวยากรณ์ 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%%ค่าจึงเป็นตัวแทนของหน้าต่างๆในดัชนี

ผลลัพธ์ที่ได้:

ป้อนคำอธิบายรูปภาพที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.