การอัพเดตดัชนีเซิร์ฟเวอร์ SQL หยุดชะงัก


13

ฉันมี 2 แบบสอบถามซึ่งเมื่อทำงานในเวลาเดียวกันจะทำให้เกิดการหยุดชะงัก

แบบสอบถาม 1 - อัปเดตคอลัมน์ซึ่งรวมอยู่ในดัชนี (ดัชนี 1):

update table1 set column1 = value1 where id = @Id

ใช้ X-Lock บน table1 จากนั้นลอง X-Lock บน index1

แบบสอบถาม 2:

select columnx, columny, etc from table1 where {some condition}

นำ S-Lock ไปที่ index1 จากนั้นลอง S-Lock บน table1

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

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

กราฟการหยุดชะงัก

คำตอบ:


11

มีวิธีการป้องกันการหยุดชะงักในขณะที่รักษาข้อความค้นหาเดียวกันหรือไม่

กราฟการหยุดชะงักแสดงให้เห็นว่าการหยุดชะงักโดยเฉพาะนี้เป็นการหยุดชะงักการแปลงที่เกี่ยวข้องกับการค้นหาบุ๊กมาร์ก (การค้นหา RID ในกรณีนี้):

กราฟการหยุดชะงัก

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

การกำจัดการหยุดชะงักต้องใช้การกำจัดหนึ่งในส่วนผสมของการหยุดชะงัก ตัวเลือกหลัก ๆ ดังต่อไปนี้:

  1. หลีกเลี่ยงการค้นหา RID โดยการทำดัชนีที่ไม่ครอบคลุม นี่อาจไม่เป็นจริงในกรณีของคุณเนื่องจากSELECTแบบสอบถามส่งคืน 26 คอลัมน์
  2. หลีกเลี่ยงการค้นหา RID โดยการสร้างดัชนีคลัสเตอร์ Proposalนี้จะเกี่ยวข้องกับการสร้างดัชนีคลัสเตอร์ในคอลัมน์ นี่เป็นสิ่งที่ควรพิจารณาแม้ว่าจะปรากฏว่าคอลัมน์นี้เป็นประเภทuniqueidentifierซึ่งอาจเป็นทางเลือกที่ดีสำหรับดัชนีคลัสเตอร์ซึ่งขึ้นอยู่กับประเด็นที่กว้างขึ้น
  3. หลีกเลี่ยงการล็อคที่ใช้ร่วมกันเมื่ออ่านโดยเปิดใช้งานREAD_COMMITTED_SNAPSHOTหรือSNAPSHOTตัวเลือกฐานข้อมูล สิ่งนี้จะต้องมีการทดสอบอย่างรอบคอบโดยเฉพาะอย่างยิ่งที่เกี่ยวกับพฤติกรรมการบล็อกที่ออกแบบมา รหัสทริกเกอร์จะต้องมีการทดสอบเพื่อให้แน่ใจว่าตรรกะทำงานอย่างถูกต้อง
  4. หลีกเลี่ยงการล็อคที่ใช้ร่วมกันเมื่ออ่านโดยใช้READ UNCOMMITTEDระดับการแยกสำหรับSELECTแบบสอบถาม ใช้คำเตือนทั้งหมด
  5. หลีกเลี่ยงการดำเนินการพร้อมกันของสองแบบสอบถามที่เป็นปัญหาโดยใช้การล็อกแอปพลิเคชันแบบเอกสิทธิ์เฉพาะบุคคล (ดูsp_getapplock )
  6. ใช้คำแนะนำการล็อคตารางเพื่อหลีกเลี่ยงการเกิดพร้อมกัน นี่เป็นค้อนที่ใหญ่กว่าตัวเลือก 5 เนื่องจากอาจส่งผลต่อการสืบค้นอื่น ๆ ไม่ใช่เฉพาะสองแบบที่ระบุในคำถาม

ฉันสามารถใช้ X-Lock กับดัชนีในธุรกรรมการปรับปรุงก่อนที่การปรับปรุงเพื่อให้แน่ใจว่าการเข้าถึงตารางและดัชนีอยู่ในลำดับเดียวกัน

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

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


จากการดูเพิ่มเติมในประเด็นที่ฉันคิดว่าการเปลี่ยนแปลงไม่น่าจะดีที่สุด มันเป็นปัญหาที่พบได้บ่อยกว่าเดิมที่ฉันรู้ได้ในตอนแรก
Dale K

1

ฉันมีปัญหาที่คล้ายกันที่เกิดขึ้นเป็นครั้งคราวและนี่คือวิธีที่ฉันใช้

  1. เพิ่มset deadlock priority low;ไปยังการเลือก ซึ่งจะทำให้แบบสอบถามนี้เป็นเหยื่อการหยุดชะงักเมื่อเกิดการชะงักงัน
  2. ตั้งค่าตรรกะการลองส่งใหม่ภายในแอปพลิเคชันของคุณเพื่อลองเลือกโดยอัตโนมัติหากมันล้มเหลวเนื่องจากการหยุดชะงัก (หรือหมดเวลา) หลังจากรอ / นอนเป็นระยะเวลาสั้น ๆ เพื่อให้การสืบค้นบล็อกเสร็จสมบูรณ์

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


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