ทำไมดัชนีที่ไม่ได้จัดกลุ่มของฉันใช้พื้นที่มากขึ้นเมื่อฉันลบแถว


22

ฉันมีตารางขนาดใหญ่ที่มี 7.5 พันล้านแถวและ 5 ดัชนี เมื่อฉันลบประมาณ 10 ล้านแถวฉันสังเกตว่าดัชนีที่ไม่ได้จัดกลุ่มดูเหมือนจะเพิ่มจำนวนหน้าเว็บที่เก็บไว้

ฉันเขียนแบบสอบถามdm_db_partition_statsเพื่อรายงานความแตกต่าง (หลัง - ก่อน) ในหน้า:

dm_db_partition_stats deltas

ดัชนี1เป็นดัชนีคลัสเตอร์ดัชนี2เป็นคีย์หลัก ส่วนอื่น ๆ นั้นไม่เป็นแบบคลัสเตอร์และไม่ซ้ำใคร

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

เมื่อลบแล้วระเบียนผีต้องย้ายไปหน้าอื่นหรือไม่ สิ่งนี้เกี่ยวข้องกับ "ตัวระบุเฉพาะ" หรือไม่

เรากำลังอยู่ระหว่างการเปิดตัว RCSI แต่ตอนนี้ RCSI ปิดอยู่

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


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

เป็นคำถามที่ดี @LaughingVergil เมื่อฉันมีคำตอบฉันจะกลับมาที่นี่เพื่อรายงาน (แต่อาจใช้เวลาสักครู่)
Michael J Swart

ในกรณีของเราการเพิ่มขึ้นนี้เป็นปรากฏการณ์ชั่วคราว ด้วยความอดทนที่เพียงพอการล้างข้อมูลผีในที่สุดก็ทำงานได้และขนาดของดัชนีลดลง
Michael J Swart

คำตอบ:


28

สถานการณ์หนึ่งที่เป็นไปได้ที่ทำให้ฉันสนุกมาก:

  • ตอนแรกแถวถูกเขียนเมื่อฐานข้อมูลไม่ได้เปิด Read Committed Snapshot (RCSI), Snapshot Isolation (SI) หรือกลุ่มความพร้อมใช้งาน (AGs)
  • เปิดใช้งาน RCSI หรือ SI หรือฐานข้อมูลถูกเพิ่มเข้าไปในกลุ่มความพร้อมใช้งาน
  • ในระหว่างการลบการประทับเวลาขนาด 14 ไบต์ถูกเพิ่มในแถวที่ถูกลบเพื่อรองรับการอ่าน RCSI / SI / AG

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

เพื่อแสดงการเติบโตฉันใช้การส่งออกฐานข้อมูลสแต็คโอเวอร์โฟลว์ (ซึ่งไม่ได้เปิดใช้งาน RCSI) และสร้างดัชนีหลายรายการในตารางโพสต์ ฉันตรวจสอบขนาดดัชนีด้วย sp_BlitzIndex @Mode = 2 (คัดลอก / วางลงในสเปรดชีตและทำความสะอาดเล็กน้อยเพื่อเพิ่มความหนาแน่นของข้อมูลให้มากที่สุด):

sp_BlitzIndex มาก่อน

ฉันลบไปแล้วประมาณครึ่งหนึ่งของแถว:

BEGIN TRAN;
DELETE dbo.Posts WHERE Id % 2 = 0;
GO

ในขณะที่การลบเกิดขึ้นอย่างน่าประหลาดใจแฟ้มข้อมูลก็เพิ่มขึ้นเพื่อรองรับการประทับเวลาด้วยเช่นกัน! รายงานการใช้งานดิสก์ SSMS แสดงกิจกรรมการเติบโต - นี่เป็นเพียงตัวอย่างด้านบน:

เหตุการณ์การเจริญเติบโต

(ต้องรักการสาธิตที่การลบทำให้ฐานข้อมูลเติบโตขึ้น) ในขณะที่การลบกำลังทำงานอยู่ฉันวิ่ง sp_BlitzIndex อีกครั้ง โปรดทราบว่าดัชนีคลัสเตอร์มีแถวน้อยลง แต่ขนาดเพิ่มขึ้นประมาณ 1.5GB ดัชนีแบบ nonclustered บน AcceptedAnswerId มีการเติบโตอย่างมาก - ดัชนีเหล่านี้มีค่าเล็กน้อยซึ่งส่วนใหญ่เป็นโมฆะดังนั้นขนาดดัชนีจึงเกือบสองเท่า!

sp_BlitzIndex ระหว่างการลบ

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


3
นี่คือคำอธิบาย ปรากฎว่ามีสถานการณ์อื่น ๆ ที่สามารถนำไปสู่การหายไป 14 ไบต์รุ่น ในการทดสอบของฉันดูเหมือนว่าการสร้างดัชนีออฟไลน์ใหม่จะสร้างแถวใหม่โดยไม่ต้องมีรุ่นไบต์
Michael J Swart
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.