การจัดทำดัชนีตั้งแต่เริ่มต้นหรือเมื่อเกิดปัญหาประสิทธิภาพ


15

คำถามของฉันเกี่ยวกับการใช้ดัชนี

  1. ฉันควรเริ่มต้นสร้างดัชนีตั้งแต่เริ่มต้นหรือเมื่อมีปัญหาเรื่องประสิทธิภาพหรือไม่

  2. นอกจากนี้เรายังสามารถสร้างดัชนีชั่วคราวขณะดำเนินการค้นหา อะไรคือข้อดีข้อเสียของเทคนิคดังกล่าว?

คำตอบ:


17

ฉันควรเริ่มต้นสร้างดัชนีตั้งแต่เริ่มต้นหรือเมื่อมีปัญหาเรื่องประสิทธิภาพหรือไม่

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

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

  • สร้างข้อ จำกัด หลักและข้อ จำกัด อื่น ๆ ของคุณ สิ่งเหล่านี้จะถูกบังคับใช้โดยดัชนีเฉพาะ

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

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

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

ปัญหาไม่ใช่เรื่องผิดปกติในแวดวง SQL Server มีการทำดัชนีมากเกินไปเนื่องจากคำแนะนำจากดัชนี DMV และดัชนี SSMS ที่ขาดหายไป ไม่มีเครื่องมือเหล่านี้ประเมินดัชนีที่มีอยู่และจะแนะนำให้คุณสร้างดัชนีคอลัมน์ 6 คอลัมน์ใหม่แทนที่จะเพิ่มคอลัมน์เดียวลงในดัชนีคอลัมน์ 5 คอลัมน์ที่มีอยู่

-- If you have this
CREATE NONCLUSTERED INDEX [IX_MyTable_MyIndex] ON [dbo].[MyTable] 
(
    [col1] ASC
    , [col2] ASC
    , [col3] ASC
    , [col4] ASC
    , [col5] ASC
)

-- But your query would benefit from the addition of a column
CREATE NONCLUSTERED INDEX [IX_MyTable_MyIndex] ON [dbo].[MyTable] 
(
    [col1] ASC
    , [col2] ASC
    , [col3] ASC
    , [col4] ASC
    , [col5] ASC
    , [col6] ASC
)

-- SSMS will suggest you create this instead
CREATE NONCLUSTERED INDEX [IX_MyTable_AnotherIndexWithTheSameColumnsAsTheExistingIndexPlusCol6] ON [dbo].[MyTable] 
(
    [col1] ASC
    , [col2] ASC
    , [col3] ASC
    , [col4] ASC
    , [col5] ASC
    , [col6] ASC
)

Kimberly Trippมีเนื้อหาที่ยอดเยี่ยมเกี่ยวกับกลยุทธ์การจัดทำดัชนีที่ SQL มุ่งเน้นนั้นสามารถใช้กับแพลตฟอร์มอื่นได้ สำหรับกลุ่ม SQL Server นั้นมีเครื่องมือที่มีประโยชน์บางอย่างสำหรับการระบุรายการซ้ำเช่นตัวอย่างด้านบน

นอกจากนี้เรายังสามารถสร้างดัชนีชั่วคราวขณะดำเนินการค้นหา อะไรคือข้อดีข้อเสียของเทคนิคดังกล่าว?

โดยทั่วไปจะใช้กับการเรียกใช้แบบสอบถามที่ไม่ค่อยเกิดขึ้น คุณต้องประเมิน:

  1. เวลาที่ใช้ในการสร้างดัชนีลดเวลาดำเนินการของแบบสอบถามหรือไม่
  2. การบำรุงรักษาค่าใช้จ่ายในการออกจากดัชนีในสถานที่เกินดุลเวลาที่ใช้ในการสร้าง / วางเมื่อจำเป็น

3
+1 Clustering Key, Foreign Key, Unique / Primary Key และไม่ไว้วางใจดัชนี DMV ที่ขาดหายไปตามตัวอักษร ... สิ่งเหล่านี้เป็นคำแนะนำที่ดี การจัดการกับดัชนีที่มีอยู่ใน SQL Server นั้นค่อนข้างง่ายต่อการตรวจสอบโดยใช้ sys.dm_db_index_usage_stats DMV ในช่วงระยะเวลาหนึ่งคุณสามารถแสดงรายการดัชนีที่ไม่ได้สแกนหรือค้นหาในขณะที่เห็นว่าดัชนีเดียวกันนี้ได้รับการปรับปรุงหลายครั้ง นี่คือสิ่งบ่งบอกถึงการทำ overindexing
Matt M

1
+1 อย่างไรก็ตาม 'สร้างดัชนีสำหรับข้อความค้นหาที่มีการคัดเลือกสูงอย่างชัดเจน' ไม่ครอบคลุมสถานการณ์อื่นทั้งหมด ดัชนีสามารถช่วยเรียงลำดับผลลัพธ์แม้ว่าแบบสอบถามของคุณจะไม่ได้เลือกอย่างสูง พวกเขายังสามารถเร่งแบบสอบถามได้หากครอบคลุมคอลัมน์ที่เลือกทั้งหมด
ไม่มีเหตุผล

1
เห็นด้วย แต่คำถามก็คือการมองหาจุดเริ่มต้นแทนที่จะเป็นเกมจบ การระบุข้อความค้นหาที่จะครอบคลุมนั้นทำได้ยากโดยไม่มีรูปแบบการใช้งานเนื่องจากคุณไม่สามารถครอบคลุมแบบสอบถามทั้งหมด
Mark Storey-Smith

8

มีความเสี่ยงที่เกี่ยวข้องกับทั้งสองวิธี:

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

คุณจะต้องฝึกฝนตัวเองเพื่อหาดัชนีที่ไม่ได้ใช้แล้วลองลบออก (PostgreSQL สามารถทำได้ แต่น่าเสียดายที่ MySQL โดยการเปรียบเทียบนั้นอ่อนแอมาก ๆ นอกกรอบนี้)

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

ความเสี่ยงที่คุณแนะนำคือคุณไม่มีช่วงเวลาที่ใหญ่พอในระหว่างที่คุณสังเกตเห็นว่าคุณต้องการดัชนีและเมื่อคุณต้องเพิ่มมัน

PostgreSQL รองรับการสร้างดัชนีCONCURRENTLYซึ่งจะลดความเครียดบางส่วนจากความต้องการเพิ่มดัชนีอย่างฉับพลัน แต่มีข้อสังเกตบางประการที่ระบุไว้ในคู่มือ


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

สิ่งที่ทำให้การอภิปรายที่ซับซ้อนเป็นพิเศษคือปกติแล้วมันจะง่ายต่อการเปลี่ยนดัชนี แต่มันยากที่จะเปลี่ยนสคีมา ฉันไม่ต้องการที่จะส่งเสริมปฏิกิริยาที่ล่าช้าของ b เป็นข้ออ้างที่จะประมาท


4

นอกจากคำตอบของมาร์คแล้ว

คุณสามารถรับรู้ได้ด้วยการทดสอบข้อมูลจริงตามปริมาณที่คาดหวัง ฉันได้เห็นหลายกรณี (มากเกินไป) หลายกรณีที่แบบสอบถามทำงานด้วย 1,000 แถว แต่ไม่นับล้านรายการ

หากทำได้ให้ทำสำเนาผลิตในภายหลัง

แน่นอนฉันได้เห็นปัญหาแปลก ๆเฉพาะในการผลิตเนื่องจากรูปแบบการใช้งานเมื่อทุกอย่างเหมือนกัน

ดัชนีชั่วคราว นอกรูปแบบการโหลด ETL หากคุณต้องการเมื่อคุณต้องการอีกครั้ง อย่าลืม: การสร้าง / วางดัชนีเป็นการเขียนและถูกบันทึก = โหลดเพิ่มเติม


3

เพียงเพื่อเพิ่มบางสิ่ง

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

นี่คือแนวทางของฉัน

  1. เช่นเดียวกับ Mark ให้สร้างดัชนีที่เหมาะสม แต่อย่าทำเกินกำหนด
  2. คุณไม่ต้องรอจนกว่าประสิทธิภาพจะช้าเพื่อสร้างดัชนีใหม่ เมื่อใดก็ตามที่คุณเขียน SQL ใหม่ให้เรียกใช้คิวรีคิวรี (ควรเปรียบเทียบกับฐานข้อมูลแยงของคุณ) คุณควรจะสามารถดูว่าจำเป็นต้องมีดัชนีใหม่หรือไม่
  3. อย่ากลัวที่จะใส่> 0หรือ> ""ในสถานที่ของคุณสำหรับคอลัมน์ที่ไม่ได้ใช้

    1. นั่นคือสมมติว่าคุณมีดัชนีใน A, B, C และ D อย่างไรก็ตามคุณมีเพียงข้อมูล A, B, D ไม่มีเหตุผลที่คุณทำไม่ได้ -
    select * from blah 
    where A="one" 
    and B="two" 
    and C>=""     --to match index
    and D="four"
    
    --This will use your existing index. No need to create a redundant one.

อีกสิ่งหนึ่งที่อยู่ในฟอรัม "dba" แต่การสร้างดัชนีควรเป็นความรับผิดชอบของนักพัฒนาไม่ใช่ของ dba (สำหรับกรณีที่แยกกันอย่างสมบูรณ์)
user606723

2
คำสั่งของคุณเกี่ยวกับพื้นที่ที่จัดทำโดยดัชนีเป็นความเข้าใจผิดเล็กน้อยมีค่าใช้จ่ายน้อยมากในดัชนีที่ไม่ใช่คลัสเตอร์ หากคุณสามารถโพสต์คำถามในจุดนั้นมันจะคุ้มค่าสำรวจเพิ่มเติม ประการที่สองฉันไม่เห็นด้วยว่าการสร้างดัชนีเป็นโดเมนของนักพัฒนา เป็นหนึ่งในพื้นที่ที่การทำงานร่วมกันระหว่างผู้พัฒนาและ DBA สามารถให้ผลลัพธ์ที่ดีที่สุด
Mark Storey-Smith

1
ฉันจะให้ตัวอย่างหนึ่งในตารางของเรา ขนาดโต๊ะ: 21052404 KB. ขนาดของดัชนีที่ไม่คลัสเตอร์ในตารางนี้: 6637470 KB ค่าใช้จ่ายน้อยมาก? ผมคิดว่าไม่. นอกจากนี้ฉันไม่ได้บอกว่า DBA ไม่ควรร่วมมือกันฉันกำลังบอกว่าควรเป็นความรับผิดชอบของนักพัฒนาในการพิจารณาว่าจำเป็นต้องมีการสร้างดัชนีใหม่หรือไม่ พวกเขาไม่ควรเขียน SQL และคาดหวังว่า dbas จะเข้าใจสิ่งนี้ด้วยตนเอง
user606723

1
คุณไม่สามารถพูดตัวเลขแบบนั้นโดยไม่มีบริบท หากไม่ระบุคอลัมน์ดัชนี NC และคีย์คลัสเตอร์จะไม่สามารถคำนวณสัดส่วนของค่าใช้จ่ายเทียบกับข้อมูลได้
Mark Storey-Smith

Touche กุญแจคือ [ตัวเลข (24), ถ่าน, วันที่] และคอลัมน์ NC คือ [วันที่, ตัวเลข (24)] (เพียงสองคอลัมน์ในดัชนีนี้โดยเฉพาะ)
user606723

2

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

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

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