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


19

ฉันมีตารางบันทึกและ LogItem ฉันกำลังเขียนแบบสอบถามเพื่อดึงข้อมูลจากทั้งสองอย่าง มีหลายพันLogsและแต่ละคนLogสามารถมีได้มากถึง 125LogItems

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

Existing Index: Non-clustered
Key Colums (LogItem): ParentLogID, DateModified, Name, DatabaseModified

Query Plan Recommendation
CREATE NONCLUSTERED INDEX [LogReportIndex]
ON [dbo].[LogItem] ([ParentLogID],[DatabaseModified])

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

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

หมายเหตุ: ฉันไม่คิดว่านี่เป็นเพราะ SQL Server กำลังแคชผลลัพธ์ของฉันฉันรันเคียวรีประมาณ 25-30 ครั้งก่อนที่ฉันจะสร้างดัชนีและใช้เวลาประมาณ 10-15 วินาทีหลังจากดัชนีตอนนี้สอดคล้องกัน ~ 1 หรือน้อยกว่า.


ก่อนที่คุณจะสร้างดัชนีที่ไม่เป็นคลัสเตอร์เพิ่มเติมแผนปฏิบัติการจริงแสดงอะไรสำหรับการใช้ดัชนี
Thomas Stringer

ประสิทธิภาพที่ปรับปรุงแล้ว 100% คืออะไร

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

@JeffO นี่คือสิ่งที่ SSMS กล่าวว่า: "ตัวประมวลผลข้อความค้นหาประมาณการว่าการใช้ดัชนีต่อไปนี้สามารถปรับปรุงต้นทุนการสืบค้นได้ 100%"

คำตอบ:


21

ลำดับของคอลัมน์ในดัชนีเป็นสิ่งสำคัญ หากการกรองต้องการคอลัมน์ 1 และ 4 จากดัชนีดัชนีจะไม่ช่วย มันจะมีประโยชน์เฉพาะเมื่อกรองตามคอลัมน์ N คอลัมน์แรก

นี่เป็นเพราะดัชนีเป็นต้นไม้ คุณไม่สามารถได้อย่างมีประสิทธิภาพเลือกโหนดทั้งหมดของต้นไม้ที่column3 = somethingเพราะพวกเขาจะกระจายอื่น ๆ สถานที่ที่อยู่ในค่าที่แตกต่างกันและcolumn1 column2แต่ถ้าคุณรู้column1และรู้column2เช่นกันการหากิ่งที่ถูกต้องในต้นไม้นั้นไม่ใช่เกมง่ายๆ


มันจะปลอดภัยหรือไม่ที่จะสมมติ (โดยทั่วไป) ฉันต้องการหนึ่งดัชนีต่อชุดของ "ที่ไหน" ส่วนคำสั่งที่จะไปที่ตารางนั้น?

ฉันเคยเพิ่มความเร็วในการค้นหาของคนอื่นเพียงแค่ทำให้แน่ใจว่ามันใช้ดัชนีตามลำดับที่ถูกต้อง

1
@Nate Broadly ใช่ บางwheres อาจทับซ้อนดังนั้นคุณอาจมีดัชนีที่อย่างครอบคลุมหลายwheres; หรือคุณสามารถเพิกเฉยบางส่วนของwhereข้อเนื่องจากการสร้างดัชนีในคอลัมน์หนึ่งจะไม่ช่วย (การเลือกน้อย); แต่กว้างใช่

@Nate คุณไม่ต้องการมีดัชนีมากกว่าที่ต้องการ แต่ละดัชนีที่ SQL ต้องรักษาจะเพิ่มค่าใช้จ่ายของตนเอง หากคุณสามารถจัดลำดับคำสั่ง WHERE ของคุณใหม่เพื่อให้ตรงกับคอลัมน์ N แรกในดัชนีที่มีอยู่นั่นจะทำให้คุณใกล้มากโดยไม่ต้องเพิ่มดัชนีเพิ่มเติม
Chuck Guy นั่น

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

12

ขอบชั้นนำของดัชนีเป็นสิ่งที่สำคัญ

ตราบใดที่การสืบค้นของคุณถูก "ครอบคลุม" โดยขอบนำของดัชนีจะมีประสิทธิภาพ โดยทั่วไปดัชนีฐานข้อมูลจะถูกนำไปใช้เป็น B-Trees และโครงสร้างของ B-Tree กำหนดว่าการค้นหาจะต้องทำในลำดับที่แน่นอนซึ่งเป็นสาเหตุที่คำสั่งของเขตข้อมูลในดัชนีคอมโพสิตมีความสำคัญ

หากคุณมี "หลุม" เช่นหากคุณค้นหาParentLogIDและDatabaseModifiedมีเพียงดัชนีใน{ParentLogID, DateModified, Name, DatabaseModified}เท่านั้น{ParentLogID}จะสามารถใช้ส่วนของดัชนีได้อย่างมีประสิทธิภาพเท่านั้น

(หมายเหตุ: DBMS บางตัวสามารถใช้{DatabaseModified}ส่วนผ่าน "skip scan" แต่แม้ว่า DBMS ของคุณจะมีประสิทธิภาพน้อยกว่าการเข้าถึงดัชนีปกติมาก)


ดังนั้นถ้าฉันมีColumns (a, b, c, d, e, f)และข้อความค้นหาส่วนใหญ่เป็น... WHERE A IN(...) AND B = 3ดัชนีของฉันIndex(a,b,c,d)ซึ่งเป็นสิ่งที่ดี แต่ก็ไม่ได้ช่วยถ้าฉันมี... WHERE A IN (...) AND D = 5ซึ่งเป็นสาเหตุที่ดัชนีใหม่ของฉันที่ฉันทำIndex(a,d)มีประสิทธิภาพดีขึ้นมากใช่มั้ย

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