เรามีฐานข้อมูลขนาดใหญ่ประมาณ 1TB ใช้ SQL Server 2014 บนเซิร์ฟเวอร์ที่ทรงพลัง ทุกอย่างทำงานได้ดีไม่กี่ปี ประมาณ 2 สัปดาห์ที่ผ่านมาเราทำการบำรุงรักษาอย่างสมบูรณ์ซึ่งรวมถึง: ติดตั้งอัปเดตซอฟต์แวร์ทั้งหมด สร้างดัชนีและไฟล์ฐานข้อมูลขนาดกะทัดรัดทั้งหมด อย่างไรก็ตามเราไม่ได้คาดหวังว่าในบางช่วงการใช้งาน CPU ของ DB จะเพิ่มขึ้นมากกว่า 100% เป็น 150% เมื่อการโหลดจริงเหมือนกัน
หลังจากการแก้ไขปัญหาจำนวนมากเราได้ จำกัด ให้แคบลงเป็นคำถามที่ง่ายมาก แต่เราไม่พบวิธีแก้ปัญหา การสืบค้นนั้นง่ายมาก:
select top 1 EventID from EventLog with (nolock) order by EventID
ใช้เวลาประมาณ 1.5 วินาทีเสมอ! อย่างไรก็ตามเคียวรีที่คล้ายกันที่มี "desc" จะใช้เวลาประมาณ 0 ms:
select top 1 EventID from EventLog with (nolock) order by EventID desc
PTable มีประมาณ 500 ล้านแถว; EventID
คือคอลัมน์ดัชนีคลัสเตอร์หลัก (เรียงลำดับASC
) ด้วยชนิดข้อมูลของ bigint (คอลัมน์ข้อมูลประจำตัว) มีหลายเธรดที่ใส่ข้อมูลลงในตารางที่ด้านบน (EventID ที่ใหญ่กว่า) และมี 1 เธรดการลบข้อมูลจากด้านล่าง (EventID ที่เล็กกว่า)
ใน SMSS เราตรวจสอบว่าคำค้นหาสองคำนั้นใช้แผนการดำเนินการเดียวกันเสมอ:
การสแกนดัชนีแบบคลัสเตอร์
หมายเลขแถวโดยประมาณและจริงมีทั้ง 1;
จำนวนการประหารชีวิตโดยประมาณและที่แท้จริงคือทั้ง 1
ค่าใช้จ่าย I / O โดยประมาณคือ 8500 (น่าจะสูง)
หากดำเนินการติดต่อกันต้นทุนการสืบค้นจะเท่ากับ 50% สำหรับทั้งคู่
ฉันอัพเดตสถิติดัชนี with fullscan
ปัญหายังคงมีอยู่ ฉันสร้างดัชนีอีกครั้งและดูเหมือนว่าปัญหาจะหายไปครึ่งวัน แต่กลับมาแล้ว
ฉันเปิดสถิติ IO ด้วย:
set statistics io on
จากนั้นเรียกใช้แบบสอบถามทั้งสองติดต่อกันและพบข้อมูลต่อไปนี้:
(สำหรับการสืบค้นแรกแบบสอบถามที่ช้า)
ตาราง 'PTable' จำนวนการสแกน 1, ตรรกะอ่าน 407670, การอ่านทางกายภาพ 0, การอ่านล่วงหน้าอ่าน 0, lob ตรรกะอ่าน 0, lob การอ่านทางกายภาพ 0, lob การอ่านล่วงหน้าอ่าน 0
(สำหรับข้อความค้นหาที่สองหมายถึงข้อความที่รวดเร็ว)
ตาราง 'PTable' จำนวนการสแกน 1, การอ่านเชิงตรรกะ 4, การอ่านทางกายภาพ 0, การอ่านล่วงหน้าอ่าน 0, lob การอ่านตรรกะ 0, lob ทางกายภาพอ่าน 0, lob การอ่านล่วงหน้าอ่าน 0
สังเกตความแตกต่างอย่างมากในการอ่านเชิงตรรกะ ดัชนีถูกใช้ในทั้งสองกรณี
การแตกตัวของดัชนีสามารถอธิบายได้เล็กน้อย แต่ฉันเชื่อว่าผลกระทบมีน้อยมาก และปัญหาไม่เคยเกิดขึ้นมาก่อน หลักฐานอื่นคือถ้าฉันเรียกใช้แบบสอบถามเช่น:
select * from EventLog with (nolock) where EventID=xxxx
แม้ว่าฉันจะตั้งค่า xxxx ให้เป็น EventID ที่เล็กที่สุดในตารางการสืบค้นนั้นรวดเร็วมาก
เราตรวจสอบแล้วและไม่มีปัญหาการล็อค / การบล็อก
หมายเหตุ: ฉันพยายามลดความซับซ้อนของปัญหาด้านบน "PTable" เป็นจริง "EventLog"; PID
คือEventID
คือ
ฉันได้รับการทดสอบผลลัพธ์เดียวกันโดยไม่มีNOLOCK
คำใบ้
ใครช่วยได้บ้าง
แผนการดำเนินการแบบสอบถามแบบละเอียดเพิ่มเติมใน XML ดังต่อไปนี้:
https://www.brentozar.com/pastetheplan/?id=SJ3eiVnob
https://www.brentozar.com/pastetheplan/?id=r1rOjVhoZ
ฉันไม่คิดว่าจะต้องจัดทำคำสั่งสร้างตาราง มันเป็นฐานข้อมูลเก่าและได้ทำงานอย่างสมบูรณ์แบบเป็นเวลานานจนกระทั่งการบำรุงรักษา เราได้ทำการวิจัยมากมายด้วยตัวเองและ จำกัด ให้แคบลงไปจนถึงข้อมูลที่ให้ไว้ในคำถามของฉัน
ตารางที่ถูกสร้างขึ้นตามปกติกับEventID
คอลัมน์เป็นคีย์หลักซึ่งเป็นคอลัมน์ประเภทidentity
bigint
ในเวลานี้ฉันเดาว่าปัญหาอยู่ที่การแตกแฟรกเมนต์ดัชนี ทันทีหลังจากสร้างดัชนีใหม่ปัญหาดูเหมือนจะหายไปครึ่งวัน แต่ทำไมมันกลับมาอย่างรวดเร็ว ... ?