ลบ vs TRUNCATE


35

ฉันพยายามทำความเข้าใจกับความแตกต่างระหว่างคำสั่งDELETEและ TRUNCATEความเข้าใจของฉันเกี่ยวกับ internals ไปบางอย่างตาม:

DELETE-> เครื่องมือฐานข้อมูลค้นหาและลบแถวออกจากหน้าข้อมูลที่เกี่ยวข้องและหน้าดัชนีทั้งหมดที่ป้อนแถวนั้น ดังนั้นยิ่งดัชนียิ่งใช้เวลาลบนานเท่าใด

TRUNCATE -> เพียงแค่ลบหน้าข้อมูลของตารางทั้งหมดออกมาซึ่งจะเป็นตัวเลือกที่มีประสิทธิภาพมากขึ้นสำหรับการลบเนื้อหาของตาราง

สมมติว่าข้างต้นถูกต้อง (โปรดแก้ไขให้ฉันถ้าไม่):

  1. โหมดการกู้คืนที่แตกต่างกันมีผลต่อแต่ละคำสั่งอย่างไร หากมีผลกระทบใด ๆ เลย
  2. เมื่อทำการลบดัชนีทั้งหมดจะถูกสแกนหรือเฉพาะดัชนีที่อยู่แถวนั้น? ฉันจะถือว่าดัชนีทั้งหมดถูกสแกน (และไม่ได้หา?)
  3. คำสั่งจำลองอย่างไร? คำสั่ง SQL ส่งและประมวลผลกับผู้สมัครสมาชิกแต่ละคนหรือไม่? หรือ MSSQL ฉลาดกว่านี้สักหน่อย

2
มีบางข้อมูลที่เกี่ยวข้องที่อยู่ในDELETEและTRUNCATEในคำตอบของคำถามนี้บนยูทิลิตี้ของไอเอ็นจีทันทีก่อนTRUNCATE DROPนอกจากนี้คุณยังสามารถขุดในบันทึกของคุณเองเพื่อศึกษาผลกระทบของคำสั่งทั้งสองโดยใช้เทคนิคที่อธิบายไว้ในคำตอบนี้
Nick Chammas

1
คำตอบนี้แสดง internals ของการดำเนินการ DELETE และ TRUNCATE คำถามแสดงให้เห็นถึงสถานการณ์ที่ TRUNCATE ทำงานได้ดีขึ้น
孔夫子

5
@idstam TRUNCATEสามารถย้อนกลับได้ นิคครอบคลุมว่าในคำตอบของเขากับคำถามที่เขาเชื่อมโยง
Mark Storey-Smith

การตัดปลายต้องได้รับอนุญาต "แก้ไขตาราง" (ในแง่ที่ว่าการตัดปลายเป็นการเปลี่ยนแทนการลบ)
crokusek

คำตอบ:


58

DELETE -> กลไกจัดการฐานข้อมูลค้นหาและลบแถวออกจากหน้าข้อมูลที่เกี่ยวข้องและหน้าดัชนีทั้งหมดที่ป้อนแถว ดังนั้นยิ่งดัชนียิ่งใช้เวลาลบนานเท่าใด

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

การลบแถว

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

ต่อการลบดัชนี

TRUNCATE -> เพียงแค่ลบหน้าข้อมูลทั้งหมดของตารางออกและทำให้ตัวเลือกนี้มีประสิทธิภาพมากขึ้นสำหรับการลบเนื้อหาของตาราง

ใช่. TRUNCATE TABLEมีประสิทธิภาพมากขึ้นด้วยเหตุผลหลายประการ:

  1. อาจจำเป็นต้องล็อคกุญแจให้น้อยลง โดยทั่วไปการตัดต้องใช้ล็อคการแก้ไขสคีมาเพียงระดับเดียวที่ระดับตาราง (และการล็อกแบบเอกสิทธิ์เฉพาะบุคคลในแต่ละส่วนจะถูกยกเลิกการจัดสรร) การลบอาจได้รับการล็อคที่ระดับความละเอียดต่ำ (แถวหรือหน้า) รวมถึงการล็อคแบบเอกสิทธิ์เฉพาะบุคคลในหน้าใด ๆ ที่ไม่ได้รับการจัดสรร
  2. การตัดปลายเท่านั้นที่รับประกันว่าหน้าทั้งหมดจะถูกจัดสรรคืนจากตารางฮีป การลบอาจปล่อยให้เพจว่างในฮีปแม้ว่าจะมีการระบุคำใบ้ล็อคตารางแบบเอกสิทธิ์เฉพาะบุคคล (ตัวอย่างเช่นหากระดับการแยกการกำหนดเวอร์ชันแถวถูกเปิดใช้งานสำหรับฐานข้อมูล)
  3. การตัดจะถูกบันทึกอย่างน้อยที่สุดเสมอ (ไม่ว่าจะใช้รูปแบบการกู้คืนใด) เฉพาะการยกเลิกการจัดสรรหน้าเท่านั้นที่จะถูกบันทึกในบันทึกธุรกรรม
  4. การตัดสามารถใช้การเลื่อนแบบเลื่อนออกหากวัตถุมีขนาด 128 หรือมากกว่านั้น การปล่อยที่เลื่อนออกไปหมายถึงงานการจัดสรรคืนจริงดำเนินการแบบอะซิงโครนัสโดยเธรดเซิร์ฟเวอร์พื้นหลัง

โหมดการกู้คืนที่แตกต่างกันมีผลต่อแต่ละคำสั่งอย่างไร มีผลกระทบใด ๆ หรือไม่?

การลบจะถูกบันทึกอย่างสมบูรณ์ตลอดเวลา (ทุกแถวที่ถูกลบจะถูกบันทึกในบันทึกธุรกรรม) มีความแตกต่างเล็ก ๆ น้อย ๆ ในเนื้อหาของบันทึกการเข้าสู่ระบบหากแบบจำลองการกู้คืนเป็นแบบอื่นนอกเหนือจากFULLนี้

เมื่อทำการลบดัชนีทั้งหมดจะถูกสแกนหรือเฉพาะดัชนีที่อยู่แถวนั้น? ฉันจะถือว่าดัชนีทั้งหมดถูกสแกน (และไม่ได้หา?)

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

แผนกว้าง 2

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

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

รายละเอียดรายการเอาท์พุท

คำสั่งจำลองอย่างไร? คำสั่ง SQL ส่งและประมวลผลกับผู้สมัครสมาชิกแต่ละคนหรือไม่? หรือว่า SQL Server นั้นฉลาดกว่านี้นิดหน่อย?

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

การอ่านที่เกี่ยวข้อง: การเพิ่มประสิทธิภาพแบบสอบถาม T-SQL ที่เปลี่ยนแปลงข้อมูล

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