คีย์หลักและดัชนี sql


106

สมมติว่าฉันมีแถว ID (int) ในฐานข้อมูลที่ตั้งเป็นคีย์หลัก หากฉันค้นหา ID บ่อยๆฉันจำเป็นต้องทำดัชนีด้วยหรือไม่? หรือว่าเป็นคีย์หลักหมายความว่ามีการจัดทำดัชนีแล้ว?

เหตุผลที่ฉันถามเป็นเพราะใน MS SQL Server ฉันสามารถสร้างดัชนีบน ID นี้ได้ซึ่งตามที่ฉันระบุไว้คือคีย์หลักของฉัน

แก้ไข: คำถามเพิ่มเติม - การจัดทำดัชนีคีย์หลักเพิ่มเติมจะเป็นอันตรายหรือไม่

คำตอบ:


73

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

ดัชนีเพิ่มเติมไม่ได้ผลดี แต่สิ่งเดียวที่เป็นอันตราย (เล็กมาก) คือขนาดไฟล์เพิ่มเติมและค่าใช้จ่ายในการสร้างแถว


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

50

อย่างที่คนอื่น ๆ พูดไปแล้วคีย์หลักจะถูกจัดทำดัชนีโดยอัตโนมัติ

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

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

CREATE NONCLUSTERED INDEX MyIndex
ON MyTable(ID)
INCLUDE (Name, Address)

ดังนั้นเมื่อคุณใช้แบบสอบถามนี้:

SELECT ID, Name, Address FROM MyTable WHERE ID > 1000

SQL Server จะให้ผลลัพธ์โดยใช้ดัชนีที่คุณสร้างขึ้นเท่านั้นและจะไม่อ่านข้อมูลใด ๆ จากตารางจริง


28

หมายเหตุ: นี่อยู่คำตอบการพัฒนาองค์กรชั้นในที่มีขนาดใหญ่

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

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

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

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

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


จะเกิดอะไรขึ้นถ้าคีย์นั้นเป็นคีย์การเพิ่มอัตโนมัติ int หรือ bigint? SQL Server ฉลาดพอที่จะไม่ทำการสแกนดัชนีเฉพาะในกรณีนี้หรือไม่?
quillbreaker

1
@quillbreaker: IDENTITYไม่รับประกันว่าฟิลด์จะไม่ซ้ำกัน IDENTITY_INSERTท้ายที่สุดผู้ใช้สามารถแทรกค่าที่ซ้ำกันได้หากเป็นผู้ใช้

ฉันรู้ว่านี่เป็นหัวข้อที่เก่าแก่ แต่ฉันไม่เข้าใจว่าการสแกนความเป็นเอกลักษณ์ของดัชนีหนึ่งจะเป็นภาระในระบบได้อย่างไร การสแกนต้นไม้ B + ควรเป็น O (log n) * v โดยที่ v ถูก จำกัด ค่าโสหุ้ยสำหรับการแตกตัวของดัชนีความสมดุลของต้นไม้ที่ไม่สมบูรณ์ ฯลฯ ดังนั้น 2 พันล้านแถวจะเป็นฐานบันทึก 2 จาก 2,000,000,000 (ค้นหาประมาณ 31 ครั้ง) พูดว่า เม็ดมีด 2 หรือ 3 หรือแม้กระทั่ง 10. 40M ต่อวันคือประมาณ 462 / วินาที ~ 100 IO ต่อเม็ดมีด ... อ๊ะ ... โอ้ ฉันเห็น. และก่อนหน้านี้ SSD จะแพร่หลาย
Charles Burns

หากคุณไม่ได้ยกเลิกข้อ จำกัด ด้านความเป็นเอกลักษณ์ค่าใช้จ่ายในการตรวจสอบความเป็นเอกลักษณ์แต่ละแถวจะไม่มากไปกว่านี้หรือ
Max Candocia

21

คีย์หลักจะถูกจัดทำดัชนีโดยค่าเริ่มต้นเสมอ

คุณสามารถกำหนดคีย์หลักใน SQL Server 2012 ได้โดยใช้ SQL Server Management Studio หรือ Transact-SQL การสร้างคีย์หลักจะสร้างดัชนีเฉพาะที่เกี่ยวข้องโดยอัตโนมัติคลัสเตอร์หรือไม่เป็นคลัสเตอร์

http://technet.microsoft.com/en-us/library/ms189039.aspx


9

นี่คือข้อความจากMSDN :

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


8

PK จะกลายเป็นดัชนีคลัสเตอร์เว้นแต่คุณจะระบุว่าไม่ใช่คลัสเตอร์


3

การประกาศPRIMARY KEYหรือUNIQUEข้อ จำกัด ทำให้ SQL Server สร้างดัชนีโดยอัตโนมัติ

สามารถสร้างดัชนีที่ไม่ซ้ำกันได้โดยไม่ต้องตรงกับข้อ จำกัด แต่จะไม่มีข้อ จำกัด (คีย์หลักหรือคีย์ที่ไม่ซ้ำกัน) หากไม่มีดัชนีที่ไม่ซ้ำกัน

จากที่นี่การสร้างข้อ จำกัด จะ:

  • ทำให้ดัชนีที่มีชื่อเดียวกันถูกสร้างขึ้น
  • ปฏิเสธการทิ้งดัชนีที่สร้างขึ้นเนื่องจากไม่อนุญาตให้มีข้อ จำกัด หากไม่มี

และในเวลาเดียวกันการลดข้อ จำกัด จะทำให้ดัชนีที่เกี่ยวข้องลดลง

ดังนั้นมีความแตกต่างที่แท้จริงระหว่าง a PRIMARY KEYหรือUNIQUE INDEX:

  • NULLไม่อนุญาตให้ใช้ค่าPRIMARY KEYแต่อนุญาตให้อยู่ในUNIQUEดัชนี และเช่นเดียวกับตัวดำเนินการชุด (UNION, EXCEPT, INTERSECT) ในที่นี้NULL = NULLซึ่งหมายความว่าคุณสามารถมีได้เพียงค่าเดียวเนื่องจากพบว่าสองค่าเป็นค่าNULLที่ซ้ำกัน
  • PRIMARY KEYอาจมีเพียงหนึ่งรายการต่อตารางในขณะที่สามารถสร้างดัชนีที่ไม่ซ้ำกันได้999 รายการ
  • เมื่อPRIMARY KEYสร้างข้อ จำกัด จะถูกสร้างเป็นคลัสเตอร์เว้นแต่จะมีดัชนีคลัสเตอร์บนตารางNONCLUSTEREDอยู่แล้วหรือใช้ในนิยาม เมื่อUNIQUEสร้างดัชนีดัชนีจะถูกสร้างขึ้นNONCLUSTEREDเว้นแต่ว่าจะไม่เฉพาะเจาะจงCLUSTEREDและไม่มีอยู่แล้ว


1

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

ตัวอย่างเช่น: ฟิลด์ A, B, C เป็นคีย์หลักดังนั้นเมื่อคุณทำการสืบค้นโดยยึดตามฟิลด์ทั้ง 3 ฟิลด์ใน WHERE CLAUSE ของคุณประสิทธิภาพจะดี แต่เมื่อคุณต้องการสอบถามด้วยฟิลด์ C เท่านั้นใน WHERE CLAUSE คุณ จะไม่ได้รับประสิทธิภาพที่ดี ดังนั้นเพื่อให้ประสิทธิภาพของคุณทำงานได้คุณจะต้องทำดัชนีฟิลด์ C ด้วยตนเอง

โดยส่วนใหญ่คุณจะไม่เห็นปัญหาจนกว่าจะมียอดบันทึกมากกว่า 1 ล้านรายการ


0

ฉันมีฐานข้อมูลขนาดใหญ่ที่ไม่มีดัชนี (แยก)

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


นั่นเป็นเพราะ PK เป็นดัชนีคลัสเตอร์ให้ดูที่แผนการสืบค้นของคุณ
SQLMenace

0

คีย์หลักจะถูกจัดทำดัชนีโดยอัตโนมัติ

คุณสามารถสร้างดัชนีเพิ่มเติมโดยใช้ pk ขึ้นอยู่กับการใช้งานของคุณ

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