ดัชนีในคอลัมน์ข้อมูลควรจะไม่เป็นแบบคลัสเตอร์หรือไม่?


19

สำหรับตารางที่มีคอลัมน์ข้อมูลประจำตัวควรสร้างดัชนี PK / ไม่ซ้ำกันแบบคลัสเตอร์หรือไม่เป็นคลัสเตอร์สำหรับคอลัมน์ข้อมูลประจำตัวหรือไม่

เหตุผลคือดัชนีอื่น ๆ จะถูกสร้างขึ้นสำหรับการค้นหา แบบสอบถามที่ใช้ดัชนี nonclustered (บนฮีป) และส่งกลับคอลัมน์ที่ไม่ครอบคลุมโดยดัชนีจะใช้ตรรกะ I / O (LIO) น้อยลงเนื่องจากไม่มีดัชนี b-tree ที่ทำคลัสเตอร์พิเศษค้นหาขั้นตอน?

create table T (
  Id int identity(1,1) primary key, -- clustered or non-clustered? (surrogate key, may be used to join another table)
  A .... -- A, B, C have mixed data type of int, date, varchar, float, money, ....
  B ....
  C ....
  ....)

create index ix_A on T (A)
create index ix_..... -- Many indexes can be created for queries

-- Common query is query on A, B, C, ....
select A, B 
from T 
where A between @a and @a+5 -- This query will have less LIO if the PK is non-clustered (seek)

select A, B, C
from T 
where B between @a and @a+5 

....

PK แบบกลุ่มบนคอลัมน์ข้อมูลประจำตัวเป็นสิ่งที่ดีเพราะ:

  1. มันเพิ่มขึ้นอย่างน่าเบื่อหน่ายดังนั้นจึงไม่มีหน้าแยกเมื่อแทรก มีการกล่าวว่าการแทรกจำนวนมากสามารถทำได้เร็วเท่ากับบนตารางฮีป (แบบไม่รวมกลุ่ม)

  2. มันแคบ

อย่างไรก็ตามแบบสอบถามในคำถามจะเร็วขึ้นโดยไม่ตั้งคลัสเตอร์หรือไม่

** อัปเดต: ** จะเกิดอะไรขึ้นถ้าIdFK ของตารางอื่น ๆ และมันจะเข้าร่วมในการค้นหาบางอย่าง?


3
มันไม่ได้ดีขึ้นหรือแย่ลงมันขึ้นอยู่กับ
Aaron Bertrand

1
@ypercube ลิงก์kejser.org/clustered-indexes-vs-heapsกล่าวว่าผู้ที่ไม่ใช่ CI จะมี LIO น้อยลง
u23432534

2
ฉันเคยอ่านบทความในอดีตและมันชี้ให้เห็นอย่างแน่นอนว่ามีหลายกรณีสำหรับดัชนีคลัสเตอร์และกรณีสำหรับฮีป มันไม่ใช่สีดำหรือขาวทั้งหมด
ypercubeᵀᴹ

4
ฉันไม่แน่ใจว่าการตอบสนองของคุณต่อ @ypercube เป็นไปตามเกณฑ์ใด ๆ ที่อ้างโดย Mr. Kejser อย่างน้อยก็มีรายละเอียดที่คุณแชร์ ในรูปแบบปัจจุบันฉันไม่แน่ใจจริง ๆ ว่าสิ่งนี้จะสร้างคำตอบที่มีประโยชน์เพราะมันจะต้องครอบคลุมเกือบทุกสถานการณ์เดียว - ซึ่งได้ทำไปแล้วในโพสต์บล็อกที่คุณอ้างถึง หากคุณสามารถให้รายละเอียดเพิ่มเติมเกี่ยวกับสถานการณ์เฉพาะของคุณได้ความรู้บางอย่างในโพสต์อาจถูกนำไปใช้
20654 swasheck เมื่อ

2
มันจะขึ้นอยู่กับสิ่งต่าง ๆ เช่น: a) เวิร์กโหลด (OLTP? OLAP? etc?), b) ขนาดตาราง (s), c) รูปแบบปกติเพียงตั้งชื่อไม่กี่ คุณไม่ได้ให้รายละเอียดเกี่ยวกับปัจจัยเหล่านี้ดังนั้นคำแนะนำใด ๆ จะขึ้นอยู่กับการคาดเดาจากสภาพแวดล้อมของคุณ นอกจากนี้คุณได้ลองรวบรวมการสืบค้นที่คุณเสนอ (ด้วยการล้างบัฟเฟอร์) และรับโพรไฟล์ IO เฉพาะต่อการกำหนดค่าและดูด้วยตัวคุณเองหรือไม่?
20654 swasheck เมื่อ

คำตอบ:


16

โดยค่าเริ่มต้น PK จะทำคลัสเตอร์และในกรณีส่วนใหญ่นี่เป็นสิ่งที่ดี อย่างไรก็ตามคำถามใดที่ควรถาม:

  • ควรทำคลัสเตอร์ PK ของฉันอย่างไร
  • คอลัมน์ใดจะเป็นคีย์ที่ดีที่สุดสำหรับดัชนีคลัสเตอร์ของฉัน

ดัชนี PK และคลัสเตอร์เป็น 2 สิ่งที่แตกต่าง:

  • PK เป็นข้อ จำกัด PK ใช้เพื่อระบุแถวที่ไม่ซ้ำกัน แต่ไม่มีแนวคิดเรื่องการจัดเก็บ อย่างไรก็ตามโดยค่าเริ่มต้น (ใน SSMS) จะมีการบังคับใช้โดยดัชนีคลัสเตอร์ที่ไม่ซ้ำกันหากดัชนีคลัสเตอร์ยังไม่ปรากฏ
  • ดัชนีแบบคลัสเตอร์เป็นดัชนีชนิดพิเศษที่จัดเก็บข้อมูลแถวที่ระดับลีฟหมายความว่ามันครอบคลุมอยู่เสมอ คอลัมน์ทั้งหมดไม่ว่าจะเป็นส่วนหนึ่งของคีย์หรือไม่ก็ตามจะถูกเก็บไว้ที่ระดับลีฟ ไม่จำเป็นต้องไม่ซ้ำกันซึ่งในกรณีนี้จะเพิ่ม uniquifier (4 ไบต์) ในคีย์คลัสเตอร์

ตอนนี้เรามีคำถาม 2 ข้อ:

  • ฉันต้องการระบุแถวในตารางของฉันโดยเฉพาะ (PK) อย่างไร
  • ฉันต้องการเก็บไว้ที่ระดับลีฟของดัชนี (ดัชนีแบบคลัสเตอร์) ได้อย่างไร

ขึ้นอยู่กับว่า:

  • คุณออกแบบโมเดลข้อมูลของคุณ
  • คุณสอบถามข้อมูลของคุณและคุณเขียนแบบสอบถามของคุณ
  • คุณแทรกหรืออัปเดตข้อมูลของคุณ
  • ...

ก่อนอื่นคุณต้องการดัชนีกลุ่มหรือไม่? หากคุณแทรกจำนวนมากจะมีประสิทธิภาพมากขึ้นในการจัดเก็บข้อมูลที่ไม่มีการเรียงลำดับไปยัง HEAP (เปรียบเทียบกับข้อมูลที่สั่งซื้อในคลัสเตอร์) มันใช้ RID (Row Identifier, 8 ไบต์) เพื่อระบุแถวที่ไม่ซ้ำกันและเก็บไว้ในหน้า

ดัชนีคลัสเตอร์ไม่ควรเป็นค่าสุ่ม ข้อมูลที่ระดับลีฟจะถูกจัดเก็บและสั่งซื้อโดยคีย์ดัชนี ดังนั้นจึงควรเติบโตอย่างต่อเนื่องเพื่อหลีกเลี่ยงการแยกส่วนหรือแยกหน้า หากสิ่งนี้ไม่สามารถทำได้โดย PK คุณควรพิจารณาคีย์อื่นเป็นตัวเลือกที่เป็นคลัสเตอร์ ดัชนีแบบกลุ่มบนคอลัมน์ identy, GUID ตามลำดับหรือแม้กระทั่งบางอย่างเช่นวันที่ของการแทรกนั้นดีจากมุมมองตามลำดับเนื่องจากแถวทั้งหมดจะถูกเพิ่มไปยังหน้าใบไม้สุดท้าย ในขณะที่ตัวระบุที่ไม่ซ้ำกันอาจมีประโยชน์กับความต้องการทางธุรกิจของคุณในฐานะที่เป็น PK แต่ไม่ควรทำคลัสเตอร์ (พวกเขาจะสั่ง / สร้างแบบสุ่ม)

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

คีย์ดัชนีคลัสเตอร์ประกอบด้วยคอลัมน์ทั้งหมดที่คุณต้องการจัดทำดัชนี คอลัมน์ที่ไม่ซ้ำกัน (4 ไบต์) จะถูกเพิ่มหากไม่มีข้อ จำกัด ที่ไม่ซ้ำกันในคอลัมน์นั้น (มูลค่าที่เพิ่มขึ้นสำหรับรายการที่ซ้ำกันเป็นโมฆะ) คีย์ดัชนีนี้จะถูกจัดเก็บหนึ่งครั้งสำหรับแต่ละแถวที่ระดับลีฟของดัชนีที่ไม่ได้เป็นคลัสเตอร์ทั้งหมดของคุณ บางส่วนจะถูกเก็บไว้หลายครั้งในระดับกลาง (สาขา) ระหว่างรูทและระดับลีฟของแผนผังดัชนี (B-tree) หากคีย์มีขนาดใหญ่เกินไปดัชนีที่ไม่ใช่คลัสเตอร์ทั้งหมดจะใหญ่ขึ้นจะต้องใช้พื้นที่จัดเก็บมากขึ้นและมากขึ้น IO, CPU, หน่วยความจำ, ... หากคุณมี PK ในชื่อ + วันเกิด + ประเทศมันมีโอกาสมากที่คีย์นี้ ไม่ใช่ผู้สมัครที่ดี มีขนาดใหญ่เกินไปสำหรับดัชนีคลัสเตอร์ Uniqueidentifier ที่ใช้ NEWSEQUENTIALID () มักจะไม่ถือว่าเป็นคีย์แคบ (16 ไบต์) แม้ว่าจะเรียงตามลำดับ

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

ดัชนีที่ไม่ได้ทำคลัสเตอร์จะมีคีย์ที่ทำคลัสเตอร์ไว้เสมอ อย่างไรก็ตามหากคอลัมน์ที่จัดทำดัชนี (+ คอลัมน์สำคัญ) ครอบคลุมอยู่จะไม่มีการค้นหาคีย์ใด ๆ ในดัชนีคลัสเตอร์ อย่าลืมว่าคุณสามารถเพิ่มรวมและตำแหน่งลงในดัชนีที่ไม่ได้ทำคลัสเตอร์ได้ (ใช้อย่างชาญฉลาด)

ดัชนีคลัสเตอร์ควรไม่ซ้ำกันและแคบที่สุดเท่าที่จะทำได้ดัชนีคลัสเตอร์ไม่ควรเปลี่ยนแปลงตลอดเวลาและควรแทรกแบบเพิ่มหน่วย

ตอนนี้ถึงเวลาที่จะเขียน SQL บางตัวซึ่งจะสร้างตารางดัชนีและข้อ จำกัด แบบคลัสเตอร์และแบบไม่รวมกลุ่ม

ทั้งหมดนี้เป็นเชิงทฤษฎีเพราะเราไม่ทราบรูปแบบข้อมูลและประเภทข้อมูลที่คุณใช้ (A และ B)


11

สำหรับตารางที่มีคีย์หลัก (PK) ในคอลัมน์ข้อมูลประจำตัวจะถูกทำคลัสเตอร์โดยค่าเริ่มต้น มันจะดีกว่าที่ไม่เป็นคลัสเตอร์หรือไม่?

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

เช่นเดียวกับตัวเลือกใด ๆ มีสถานการณ์ที่แตกต่างกันเสมอเมื่อต้องการให้ตัวเลือกอื่นอยู่เสมอ แต่ DBA ที่มีประสบการณ์ควรตระหนักถึงค่าเริ่มต้นและสามารถแทนที่ได้ตามความเหมาะสม ดูคำถามที่พบบ่อยที่เกี่ยวข้องซึ่งจะต้องประกาศคีย์หลักเมื่อใด .

คำถามในคำถามจะเร็วขึ้นหรือไม่โดยไม่ตั้งค่าเป็นคลัสเตอร์หรือไม่

ใช่ แต่มีข้อแม้

การค้นหา RID นั้นมีประสิทธิภาพมากกว่าการค้นหาคีย์ แม้ว่าเพจที่ต้องการทั้งหมดจะอยู่ในหน่วยความจำ (เป็นไปได้มากสำหรับระดับบนของดัชนี) มีค่าใช้จ่ายของ CPU ที่เกี่ยวข้องกับการนำทางดัชนี b-tree ที่ทำคลัสเตอร์ ดังนั้น SQL Server สามารถทำการค้นหา RID ได้มากกว่าการค้นหาคีย์ต่อหน่วยเวลา CPU

คำเตือน

ข้างต้นมักจะไม่ได้เป็นปัจจัยกำหนดเมื่อตัดสินใจว่าจะโครงสร้างตารางเป็นกองหรือไม่ มันจะต้องทำไม่ได้เพื่อหลีกเลี่ยงการค้นหา (ใช้ดัชนีครอบคลุม) และจำนวนการค้นหาจะต้องมีขนาดใหญ่พอที่จะมีผลกระทบต่อการวัดผล (และที่สำคัญ) ต่อประสิทธิภาพการทำงานให้กับสภาพแวดล้อมของฮาร์ดแวร์และภาระงาน

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

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

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


8

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

แต่ดูเหมือนว่าทั้งคีย์หลักและดัชนีแบบคลัสเตอร์เป็นแนวคิดที่มีคุณค่าในฐานข้อมูลส่วนใหญ่

ให้เราดูที่เอกสารเซิร์ฟเวอร์ SQL เพื่อดูคำอธิบายบางส่วนของตัวเลือกการจัดทำดัชนีบางอย่างที่แสดงด้านล่าง

ดัชนีแบบคลัสเตอร์: https://msdn.microsoft.com/en-us/library/ms190457.aspx

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

คีย์หลัก: https://msdn.microsoft.com/en-us/library/ms190457.aspx

  • ตารางสามารถมีข้อ จำกัด หลักของคีย์เดียวเท่านั้น

  • คอลัมน์ทั้งหมดที่กำหนดไว้ภายในข้อ จำกัด หลักของคีย์จะต้องกำหนดเป็น NOT NULL

  • คีย์หลักสามารถสร้างเป็นดัชนีแบบคลัสเตอร์ (ค่าเริ่มต้นหากไม่มีดัชนีแบบคลัสเตอร์) หรือดัชนีแบบไม่เป็นกลุ่ม

ดัชนีที่ไม่ซ้ำ: https://msdn.microsoft.com/en-us/library/ms187019.aspx

  • เมื่อคุณสร้างข้อ จำกัด UNIQUE ดัชนี nonclustered ที่ไม่ซ้ำกันจะถูกสร้างขึ้นเพื่อบังคับใช้ข้อ จำกัด UNIQUE โดยค่าเริ่มต้น

  • คุณสามารถระบุ UNIQUE Clustered Index ได้หากไม่มี Clustered Index อยู่แล้วสำหรับตาราง

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

เมื่อใดที่ฉันจะได้รับประโยชน์จากคีย์หลักที่ถูกแยกออกจากดัชนีแบบกลุ่ม

บางทีเมื่อดัชนีแบบกลุ่มเป็นแบบกว้าง (ตัวอย่างเช่น 5 คอลัมน์ของข้อมูลแบบข้อความ แต่คีย์หลักมีขนาดเล็ก (INT หรือ BIGINT) เช่นคุณดูเหมือนจะอธิบาย

  • ดัชนีแบบคลัสเตอร์แบบกว้างจะอนุญาตให้คุณเลือกแถวจากดัชนีอย่างรวดเร็วสำหรับชุดย่อยของแบบสอบถามที่ให้คำตอบแบบอนุกรมจากดัชนีแบบคลัสเตอร์ (หรือที่เรียกว่าตาราง ) ตัวอย่างเช่นดัชนี 5 คอลัมน์แบบคลัสเตอร์จะรองรับการสแกนคอลัมน์ C1, C2, C3, C4, C5 หรือ C1, C2, C3, C4 และอื่น ๆ ลงไปที่ C1
  • หมายเหตุ: หากแถวมีขนาดใหญ่อาจทำให้คุณได้รับผลประโยชน์ด้านความเร็วในการเลือกชุดอนุกรมของแถวโดยเฉพาะถ้าคอลัมน์อื่น ๆ ในตารางรวมอยู่ในชุดผลลัพธ์เป็นประจำ
  • ในกรณีนั้นคุณสามารถใช้คีย์หลักสำหรับการอ้างอิงที่สมบูรณ์เพื่อระบุค่าที่ต้องการเป็นคีย์ต่างประเทศเพื่อ จำกัด แถวในตารางอื่น ๆ PK มีขนาดเล็กและดังนั้น FK จึงมีผลกระทบเล็กน้อยกับขนาดของตารางอ้างอิง
  • อย่างไรก็ตามโปรดทราบว่าดัชนีใด ๆ ที่สร้างขึ้นในตารางที่มีดัชนีแบบกลุ่มจะรวมคอลัมน์คลัสเตอร์ทั้งหมดในดัชนีอื่น ๆ ที่คุณสร้างในตารางนี้ ดัชนีแบบคลัสเตอร์แบบกว้างจะขยายขนาดของดัชนีที่ไม่ใช่แบบคลัสเตอร์ทั้งหมดบนตารางนั้น

คุณควรสร้างคีย์หลักเพียงอย่างเดียวเพื่อเป็นดัชนีแบบกลุ่มหรือไม่

  • หากคุณมีคีย์หลักขนาดเล็ก (INT หรือ BIGINT) และเป็นดัชนีแบบกลุ่มค่าใช้จ่ายของคอลัมน์คลัสเตอร์จะค่อนข้างเล็ก แม้ว่าคีย์หลักแบบคลัสเตอร์ในกรณีนี้จะมีอยู่ในทุกดัชนีในตารางนี้ แต่จะมีค่าใช้จ่ายน้อยกว่า Wide Wide ที่กล่าวถึงข้างต้น

  • ดัชนีคีย์หลักกลุ่มนี้มักจะไม่นำเสนอเส้นทางที่ง่ายต่อการเลือกหลายแถวตามลำดับ

  • ตอนนี้คุณได้สร้างคีย์หลักแบบคลัสเตอร์แล้วคอลัมน์อื่น ๆ ที่คุณเคยวางแผนที่จะรวมไว้ในดัชนีแบบกลุ่มเป็นอย่างไร

  • สร้างดัชนีที่ไม่ซ้ำ (หรือไม่ซ้ำ) ตามต้องการเพื่อทำดัชนีเกณฑ์การค้นหาแบบกว้างของคอลัมน์ C1, C2, C3, C4, C5 ค่าในดัชนี“ การเลียนแบบกลุ่ม” นี้สามารถใช้เป็นเส้นทางการค้นหาที่รวดเร็วขึ้นสำหรับ 5 คอลัมน์เหล่านั้น INCLUDE (Doctor_Name, Diagnosis_Synopsis)หากมีคอลัมน์ที่ไม่ใช่การจัดทำดัชนีหรือสองที่ได้รับการคัดเลือกเป็นประจำเช่นกันพวกเขาสามารถรวมอยู่ในดัชนีด้วย

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

คุณต้องการดัชนีแบบกลุ่มหรือไม่?

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

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

  • หากไม่มีดัชนีแบบกลุ่มข้อมูลของคุณจะถูกจัดเก็บเป็นฮีปพร้อมตัวระบุแถว (RID) ซึ่งไม่ใช่กลไกการค้นหาที่ดีเลย แต่ตามที่กล่าวไว้ก่อนหน้านี้คุณสามารถสร้างดัชนีที่ไม่ซ้ำกันและไม่ซ้ำกันเพื่อจัดการคิวรีของคุณ

ซึ่งตอนนี้จะนำคุณไปสู่การพิจารณากอง:

ฮีปและดัชนี: https://msdn.microsoft.com/en-us/library/hh213609.aspx

  • เมื่อตารางถูกเก็บเป็นฮีปแต่ละแถวจะถูกระบุโดยการอ้างอิงถึงตัวระบุแถว (RID) ซึ่งประกอบด้วยหมายเลขไฟล์หมายเลขหน้าข้อมูลและสล็อตในหน้า id ของแถวเป็นโครงสร้างขนาดเล็กและมีประสิทธิภาพ (แต่ไม่ใช่ดัชนี )
  • บางครั้งสถาปนิกข้อมูลที่ใช้กองเมื่อข้อมูลที่สามารถเข้าถึงได้เสมอผ่านดัชนี nonclustered และกรมชลประทานมีขนาดเล็กกว่าคีย์ดัชนีคลัสเตอร์

แต่ถ้าคุณมี 'ฮอตสปอต' ในชุดข้อมูลขนาดใหญ่คุณสามารถดูดัชนีประเภทอื่นได้ด้วย:

ดัชนีที่กรอง: https://msdn.microsoft.com/en-us/library/cc280372.aspx

  • ดัชนีตัวกรองที่ได้รับการออกแบบมาอย่างดีจะช่วยปรับปรุงประสิทธิภาพการค้นหาและคุณภาพของแผนปฏิบัติการเนื่องจากมีขนาดเล็กกว่าดัชนีแบบไม่เต็มตารางและมีการกรองสถิติ สถิติกรองมีความถูกต้องมากกว่าสถิติแบบเต็มรูปแบบตารางเพราะพวกเขาครอบคลุมเฉพาะแถวในดัชนีกรองที่

  • ดัชนีที่กรองมีจำนวนข้อ จำกัด ที่ระบุไว้ในลิงค์ไปยังดัชนีที่ถูกกรอง

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

http://use-the-index-luke.com/blog/2014-01/unreasonable-defaults-primary-key-clustering-key

แต่ในที่สุดมันก็กลับมาที่การทำความเข้าใจแอปพลิเคชันของคุณและออกแบบรหัสตารางดัชนีและอื่น ๆ เพื่อให้เหมาะกับงานที่คุณกำลังทำ


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

-2

สองประเด็นที่ควรพิจารณา

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

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

ฉันคิดว่าคุณจะได้รับประโยชน์มากที่สุดจากดัชนีแบบคลัสเตอร์ที่ครอบคลุมข้อความค้นหาที่ขอสแกนช่วงที่สำคัญและภาคแสดงเพิ่มเติมที่อ้างอิงคอลัมน์อื่น ๆ


อัตรานี้ต้องสูงเท่าไหร่เพื่อให้เป็นปัญหาจริง
ypercubeᵀᴹ

@ypercube ฉันสามารถพูดว่า "มันขึ้นอยู่กับ"? เพราะมัน ในกรณีที่ไม่มีทริกเกอร์บนโต๊ะฉันคาดว่าจะเริ่มพบกับการโต้เถียงกับเธรดโหลจำนวนรวม 1K แทรกต่อวินาที
mustaccio

กรณีที่อยู่ในจุด: blogs.msdn.com/b/sqlserverfaq/archive/2010/05/27/ …
mustaccio

ฉันไม่เห็นด้วย แต่ฉันถูกถามว่าจะไปไกลแค่ไหนกับจุดร้อนเดียว ฉันจำได้ว่าเห็นบทความเกี่ยวกับการแทรกแถว 30K ต่อวินาทีในตารางที่มีตัวตนเป็น CI (หากหน่วยความจำให้บริการฉันดี) แต่ฉันไม่พบโพสต์บล็อก
ypercubeᵀᴹ

การสนทนานี้ไม่มีจุดหมายหากไม่มีเวิร์กโหลดที่เป็นรูปธรรมที่รันกับสกีมาที่เป็นรูปธรรมบนฮาร์ดแวร์เฉพาะ ฉันหวังว่าเราทุกคนสามารถยอมรับว่าดัชนีในลำดับที่เพิ่มขึ้นอย่างน่าเบื่อจะสร้าง "ฮอตสปอต"; ไม่ว่าจะเป็นการสร้างคอขวดที่ยอมรับไม่ได้และควรให้ความสำคัญกับสิ่งนั้นหรือไม่นั้นขึ้นอยู่กับสถานการณ์
mustaccio
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.