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


22

ฉันค่อนข้างรู้คำตอบสำหรับคำถามนี้อยู่แล้ว แต่ฉันรู้สึกเสมอว่ามีมากกว่าที่ฉันต้องรับในหัวข้อ

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

ลองนึกภาพโต๊ะแบบนี้:

id int pk/uid
name varchar(50)
customerId int (foreign key)
dateCreated datetime

ผมอาจจะเห็นดัชนีเดียวรวมทั้งname, customerIdและdateCreatedสาขา

แต่ความเข้าใจของฉันคือว่าดัชนีดังกล่าวจะไม่ถูกใช้ในแบบสอบถามเช่น:

SELECT [id], [name], [customerId], [dateCreated]
   FROM Representatives WHERE customerId=1 
   ORDER BY dateCreated

สอบถามเช่นมันดูเหมือนว่าผมว่าเป็นความคิดที่ดีกว่าจะเป็นดัชนีรวมทั้งcustomerIdและdateCreatedเขตที่มีcustomerIdข้อมูลเป็น 'ครั้งแรก' สิ่งนี้จะสร้างดัชนีที่จะมีการจัดระเบียบข้อมูลในลักษณะที่แบบสอบถามนี้สามารถค้นหาสิ่งที่ต้องการได้อย่างรวดเร็ว - ตามลำดับที่ต้องการ

อีกสิ่งที่ฉันเห็นบ่อยครั้งเป็นอันดับแรกคือดัชนีแต่ละรายการในแต่ละฟิลด์ เพื่อให้แต่ละคนบนname, customerIdและdateCreatedสาขา

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


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

แต่ฉันคิดว่าสิ่งที่ฉันถามคือ 'จุดเริ่มต้นทั่วไป' สำหรับดัชนีความคิดของการมีดัชนีเฉพาะสำหรับแบบสอบถามที่ดึงบ่อยและฟิลด์ในส่วนคำสั่ง WHERE หรือ ORDER BY เหมาะสมหรือไม่

คำตอบ:


27

คุณมีสิทธิ์ที่แบบสอบถามตัวอย่างของคุณจะไม่ใช้ดัชนีนั้น

ตัววางแผนคิวรีจะพิจารณาใช้ดัชนีหาก:

  • เขตข้อมูลทั้งหมดที่อยู่ในนั้นจะถูกอ้างอิงในแบบสอบถาม
  • มีการอ้างอิงบางฟิลด์ที่เริ่มต้นจากจุดเริ่มต้น

จะไม่สามารถใช้ดัชนีที่ขึ้นต้นด้วยเขตข้อมูลที่ไม่ได้ใช้โดยแบบสอบถาม

ดังนั้นสำหรับตัวอย่างของคุณ:

SELECT [id], [name], [customerId], [dateCreated]
   FROM Representatives WHERE customerId=1 
   ORDER BY dateCreated

มันจะพิจารณาดัชนีเช่น:

[customerId]
[customerId], [dateCreated]
[customerId], [dateCreated], [name]

แต่ไม่:

[name], [customerId], [dateCreated]

หากพบว่าทั้งสอง[customerId]และ[customerId], [dateCreated], [name]การตัดสินใจที่จะเลือกอย่างใดอย่างหนึ่งมากกว่าอื่น ๆ จะขึ้นอยู่กับสถิติดัชนีซึ่งขึ้นอยู่กับการประมาณการของความสมดุลของข้อมูลในเขตข้อมูล หาก[customerId], [dateCreated]มีการกำหนดไว้มันควรจะชอบมากกว่าสองข้อนี้เว้นแต่คุณจะให้คำแนะนำดัชนีเฉพาะเจาะจงกับสิ่งที่ตรงกันข้าม

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

ดัชนีเฉพาะสำหรับข้อความค้นหาบ่อย ๆ ที่อาจช้าเนื่องจากการสแกนตารางหรือดัชนีนั้นเป็นความคิดที่ดี แต่อย่าหักโหมเพราะคุณสามารถแลกเปลี่ยนประเด็นด้านประสิทธิภาพหนึ่งเรื่องสำหรับอีกเรื่องได้ [customerId], [dateCreated]ตัวอย่างเช่นหากคุณกำหนดเป็นดัชนีโปรดจำไว้ว่าตัววางแผนคิวรีจะสามารถใช้สิ่งนั้นสำหรับคิวรีที่จะใช้ดัชนีใน[customerId]กรณีที่มีอยู่ ในขณะที่ใช้เพียง[customerId]เล็กน้อยจะมีประสิทธิภาพมากกว่าการใช้ดัชนีผสมนี่อาจจะลดลงเมื่อสิ้นสุดการมีดัชนีสองรายการแข่งขันกันสำหรับพื้นที่ใน RAM แทนที่จะเป็นหนึ่ง (แม้ว่าถ้าชุดการทำงานปกติของคุณพอดีกับ RAM ได้อย่างง่ายดายการแข่งขันหน่วยความจำเพิ่มเติมนี้อาจไม่ ปัญหา)


+1; ข้อมูลที่ดีโดยเฉพาะอย่างยิ่งการแจ้งเตือน (ซึ่งฉันมักจะลืม!) ว่าผู้วางแผนสามารถใช้ดัชนีผสมในเวลาที่ต้องการเพียงเขตข้อมูลแรกจากแบบสอบถาม
Andrew Barber เมื่อ

6

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

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

กลยุทธ์ของฉันสำหรับการออกแบบดัชนีคือดัชนี:

  • ฟิลด์ที่ใช้ใน WHERE (ตามลำดับการเลือก)
  • ฟิลด์ที่ใช้ใน ORDER BY
  • รวมฟิลด์อื่น ๆ (ถ้าจำเป็น) เพื่อสร้างดัชนีครอบคลุม

ดังนั้นสำหรับตัวอย่างของคุณ:

SELECT [id], [name], [customerId], [dateCreated]
   FROM Representatives WHERE customerId=1 
   ORDER BY dateCreated

ฉันอาจจะออกแบบดัชนีใน (CustomerID, dateCreated) รวม (id, name) ดัชนีที่ครอบคลุมนี้หมายถึงคิวรีไม่จำเป็นต้องไปที่ตารางเดิมเพื่อปรับปรุงประสิทธิภาพอย่างมากมาย

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


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