ในหน่วยเก็บข้อมูลเชิงแถวของ SQL Server ดัชนีทั้งแบบคลัสเตอร์และแบบไม่รวมกลุ่มถูกจัดเป็นแผนผัง B
( แหล่งรูปภาพ )
ความแตกต่างที่สำคัญระหว่างดัชนีคลัสเตอร์และดัชนีที่ไม่ใช่คลัสเตอร์คือระดับลีฟของดัชนีคลัสเตอร์คือตาราง สิ่งนี้มีสองนัย
- แถวบนหน้าดัชนีจุดคลัสเตอร์จะมีบางสิ่งบางอย่างสำหรับแต่ละคอลัมน์ (ไม่กระจาย) ในตาราง (ทั้งค่าหรือตัวชี้ไปยังค่าจริง)
- ดัชนีคลัสเตอร์เป็นสำเนาหลักของตาราง
ดัชนีที่ไม่ใช่คลัสเตอร์สามารถทำชี้ที่ 1 ได้โดยใช้INCLUDE
ส่วน (ตั้งแต่ SQL Server 2005) เพื่อรวมคอลัมน์ที่ไม่ใช่คีย์ทั้งหมดไว้อย่างชัดเจน แต่เป็นดัชนีรองและมีสำเนาอีกรอบของข้อมูลอยู่เสมอ (ตารางตัวเอง)
CREATE TABLE T
(
A INT,
B INT,
C INT,
D INT
)
CREATE UNIQUE CLUSTERED INDEX ci ON T(A,B)
CREATE UNIQUE NONCLUSTERED INDEX nci ON T(A,B) INCLUDE (C,D)
ดัชนีทั้งสองด้านบนจะเหมือนกันเกือบทั้งหมด ด้วยหน้าดัชนีระดับบนที่มีค่าสำหรับคอลัมน์สำคัญA,B
และหน้าระดับใบที่มีA,B,C,D
สามารถมีดัชนีคลัสเตอร์เดียวได้ต่อตารางเนื่องจากแถวข้อมูลสามารถเรียงลำดับได้เพียงหนึ่งคำสั่งเท่านั้น
ข้อความข้างต้นจาก SQL Server หนังสือออนไลน์ทำให้เกิดความสับสนมาก
ในความคิดของฉันมันจะเป็นวลีที่ดีกว่ามาก
สามารถมีดัชนีคลัสเตอร์เดียวได้ต่อตารางเนื่องจากแถวระดับลีฟของดัชนีคลัสเตอร์เป็นแถวของตาราง
ราคาหนังสือออนไลน์ไม่ถูกต้อง แต่คุณควรชัดเจนว่า "การเรียงลำดับ" ของดัชนีทั้งแบบคลัสเตอร์และแบบคลัสเตอร์นั้นไม่สมเหตุสมผล หากคุณอ่านหน้าเว็บที่ระดับลีฟโดยทำตามรายการที่เชื่อมโยงและอ่านแถวในหน้าตามลำดับอาร์เรย์สล็อตคุณจะอ่านแถวดัชนีตามลำดับเรียง แต่จริง ๆ แล้วหน้าเว็บอาจไม่เรียงลำดับ ความเชื่อที่จัดขึ้นโดยทั่วไปว่าด้วยดัชนีกลุ่มแถวจะถูกเก็บไว้ในดิสก์ตามลำดับเช่นเดียวกับคีย์ดัชนีเป็นเท็จ
นี่จะเป็นการใช้งานที่ไร้สาระ ตัวอย่างเช่นหากมีการแทรกแถวลงในตารางกลางของ 4GB เซิร์ฟเวอร์ SQL ไม่จำเป็นต้องคัดลอกข้อมูล 2GB ขึ้นในไฟล์เพื่อให้มีที่ว่างสำหรับแถวที่แทรกใหม่
การแบ่งหน้าเกิดขึ้นแทน แต่ละหน้าที่ระดับลีฟของดัชนีทั้งคลัสเตอร์และไม่ใช่คลัสเตอร์มีที่อยู่ ( File:Page
) ของหน้าถัดไปและก่อนหน้าในลำดับคีย์แบบโลจิคัล หน้าเหล่านี้ไม่จำเป็นต้องต่อเนื่องกันหรือเรียงตามลำดับความสำคัญ
เช่นกลุ่มเพจที่เชื่อมโยงอาจเป็น 1:2000 <-> 1:157 <-> 1:7053
เมื่อมีการแบ่งหน้าเกิดขึ้นหน้าใหม่จะถูกจัดสรรจากที่ใดก็ได้ในกลุ่มไฟล์ (จากขอบเขตผสมสำหรับตารางเล็กหรือขอบเขตว่างเปล่าที่ไม่ว่างเปล่าที่เป็นของวัตถุนั้นหรือขอบเขตสม่ำเสมอที่จัดสรรใหม่) สิ่งนี้อาจไม่อยู่ในไฟล์เดียวกันหากกลุ่มไฟล์มีมากกว่าหนึ่ง
ระดับที่ลำดับเชิงตรรกะและความแตกต่างจากเวอร์ชันทางกายภาพในอุดมคติคือระดับของการแตกแฟรกเมนต์เชิงตรรกะ
ในฐานข้อมูลที่สร้างขึ้นใหม่ด้วยไฟล์เดียวฉันวิ่งต่อไปนี้
CREATE TABLE T
(
X TINYINT NOT NULL,
Y CHAR(3000) NULL
);
CREATE CLUSTERED INDEX ix
ON T(X);
GO
--Insert 100 rows with values 1 - 100 in random order
DECLARE @C1 AS CURSOR,
@X AS INT
SET @C1 = CURSOR FAST_FORWARD
FOR SELECT number
FROM master..spt_values
WHERE type = 'P'
AND number BETWEEN 1 AND 100
ORDER BY CRYPT_GEN_RANDOM(4)
OPEN @C1;
FETCH NEXT FROM @C1 INTO @X;
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO T (X)
VALUES (@X);
FETCH NEXT FROM @C1 INTO @X;
END
จากนั้นตรวจสอบเค้าโครงหน้าด้วย
SELECT page_id,
X,
geometry::Point(page_id, X, 0).STBuffer(1)
FROM T
CROSS APPLY sys.fn_PhysLocCracker( %% physloc %% )
ORDER BY page_id
ผลลัพธ์ได้ทั่วทุกสถานที่ แถวแรกในการสั่งซื้อคีย์ (ที่มีค่า 1 - เน้นด้วยลูกศรด้านล่าง) อยู่ในเกือบหน้าทางกายภาพสุดท้าย
การแตกแฟรกเมนต์สามารถลดหรือลบได้โดยสร้างใหม่หรือจัดโครงสร้างดัชนีใหม่เพื่อเพิ่มความสัมพันธ์ระหว่างลำดับโลจิคัลและลำดับฟิสิคัล
หลังจากวิ่ง
ALTER INDEX ix ON T REBUILD;
ฉันได้รับดังต่อไปนี้
หากตารางไม่มีดัชนีคลัสเตอร์จะเรียกว่าฮีป
ดัชนีที่ไม่ใช่คลัสเตอร์สามารถสร้างได้บนทั้งฮีปหรือดัชนีคลัสเตอร์ พวกเขามักจะมีที่ตั้งแถวกลับไปที่ตารางฐาน ในกรณีของฮีปนี่คือตัวระบุแถวจริง (กำจัด) และประกอบด้วยสามคอมโพเนนต์ (ไฟล์: หน้า: สล็อต) ในกรณีของดัชนีแบบคลัสเตอร์ตัวระบุตำแหน่งแถวจะเป็นแบบลอจิคัล (คีย์ดัชนีแบบคลัสเตอร์)
สำหรับกรณีหลังหากดัชนีที่ไม่ได้ทำคลัสเตอร์รวมถึงคอลัมน์คีย์ CI ตามธรรมชาติแล้วไม่ว่าจะเป็นคอลัมน์คีย์ NCI หรือINCLUDE
คอลัมน์ -d ดังนั้นจะไม่มีการเพิ่มอะไรเลย มิฉะนั้นคอลัมน์คีย์ CI ที่หายไปจะถูกเพิ่มเข้าใน NCI อย่างเงียบ ๆ
SQL Server จะตรวจสอบให้แน่ใจเสมอว่าคอลัมน์คีย์นั้นไม่ซ้ำกันสำหรับดัชนีทั้งสองประเภท กลไกที่สิ่งนี้ถูกบังคับใช้สำหรับดัชนีที่ไม่ได้ประกาศว่าไม่เหมือนกันแตกต่างกันระหว่างดัชนีทั้งสองชนิด
ดัชนีแบบคลัสเตอร์จะได้รับการuniquifier
เพิ่มสำหรับแถวใด ๆ ที่มีค่าคีย์ที่ซ้ำกับแถวที่มีอยู่ นี่เป็นเพียงจำนวนเต็มน้อยไปหามาก
สำหรับดัชนีที่ไม่ใช่คลัสเตอร์ไม่ได้ประกาศว่าเป็น SQL Server ที่ไม่ซ้ำกันจะเพิ่มตัวระบุแถวเข้าไปในคีย์ดัชนีที่ไม่ใช่คลัสเตอร์ สิ่งนี้ใช้ได้กับทุกแถวไม่ใช่เฉพาะแถวที่ซ้ำกันจริงๆ
ระบบการตั้งชื่อแบบเทียบกับแบบไม่ทำคลัสเตอร์ยังใช้สำหรับดัชนีที่จัดเก็บคอลัมน์ กระดาษการปรับปรุงสถานะร้านค้าคอลัมน์เซิร์ฟเวอร์ SQL
แม้ว่าข้อมูลที่จัดเก็บคอลัมน์ไม่ได้ "คลัสเตอร์" จริง ๆ ในคีย์ใด ๆ เราตัดสินใจที่จะเก็บแบบแผน SQL Server แบบดั้งเดิมไว้เพื่ออ้างอิงถึงดัชนีหลักเป็นดัชนีแบบคลัสเตอร์