มีประโยชน์ใด ๆ ที่น่าเชื่อถือในการวนรอบในแผนแรก?
ขึ้นอยู่กับสิ่งที่คุณพิจารณาว่า "น่าเชื่อถือ" แต่คำตอบตามรูปแบบต้นทุนคือใช่ แน่นอนว่านี่เป็นเรื่องจริงเพราะเครื่องมือเพิ่มประสิทธิภาพจะเลือกแผนการที่ถูกที่สุดที่พบเสมอ
คำถามที่แท้จริงคือสาเหตุที่รูปแบบต้นทุนพิจารณาแผนด้วยสปูลราคาถูกกว่ามากโดยไม่มีแผน พิจารณาแผนโดยประมาณที่สร้างขึ้นสำหรับตารางใหม่ (จากสคริปต์ของคุณ) ก่อนที่จะเพิ่มแถวใด ๆ ในร้านเดลต้า:
DELETE Fact.RecordedMetricsDetail
WHERE MeasurementTime < DATEADD(day,-1,GETUTCDATE())
OPTION (RECOMPILE);
ค่าใช้จ่ายโดยประมาณสำหรับแผนนี้มีขนาดใหญ่771,734 หน่วย :
ค่าใช้จ่ายเกือบทั้งหมดที่เกี่ยวข้องกับการลบดัชนีแบบกลุ่มเนื่องจากการลบที่คาดว่าจะส่งผลใน I / O แบบสุ่มอย่างมาก นี่เป็นเพียงตรรกะทั่วไปที่ใช้กับการปรับเปลี่ยนข้อมูลทั้งหมด ตัวอย่างเช่นชุดการแก้ไขที่ไม่เรียงลำดับของดัชนี b-tree จะถือว่าส่งผลให้ I / O แบบสุ่มส่วนใหญ่มีค่าใช้จ่าย I / O สูงที่เกี่ยวข้อง
แผนเปลี่ยนแปลงข้อมูลอาจมีการเรียงลำดับเพื่อนำเสนอแถวในลำดับที่จะส่งเสริมการเข้าถึงตามลำดับด้วยเหตุผลด้านต้นทุนเหล่านี้ ผลกระทบจะรุนแรงขึ้นในกรณีนี้เนื่องจากตารางถูกแบ่งพาร์ติชัน พาร์ติชันมากจริง ๆ แล้ว สคริปต์ของคุณสร้าง 15,000 รายการ การอัปเดตแบบสุ่มไปยังตารางที่มีการแบ่งพาร์ติชั่นนั้นมีราคาสูงโดยเฉพาะอย่างยิ่งเนื่องจากราคาเพื่อสลับพาร์ติชั่น (rowets) มิดสตรีมจะได้รับค่าใช้จ่ายสูงเช่นกัน
ปัจจัยหลักสุดท้ายที่ต้องพิจารณาคือแบบสอบถามแบบใช้ปรับปรุงอย่างง่ายด้านบน (โดยที่ 'อัพเดต' หมายถึงการดำเนินการเปลี่ยนแปลงข้อมูลใด ๆ รวมถึงการลบ) ที่มีคุณสมบัติเหมาะสมสำหรับการเพิ่มประสิทธิภาพที่เรียกว่า "การแบ่งปัน rowset" อัปเดตตาราง แผนการดำเนินการยังคงแสดงโอเปอเรเตอร์ที่แยกกันสองตัว แต่อย่างไรก็ตามมีเพียงหนึ่ง rowset ที่ใช้
ฉันพูดถึงสิ่งนี้เนื่องจากความสามารถในการใช้การเพิ่มประสิทธิภาพนี้หมายถึงเครื่องมือเพิ่มประสิทธิภาพใช้เส้นทางรหัสที่ไม่ได้พิจารณาถึงประโยชน์ที่อาจเกิดขึ้นจากการเรียงลำดับอย่างชัดเจนเพื่อลดต้นทุนของการสุ่ม I / O ในกรณีที่ตารางเป็น b-tree สิ่งนี้สมเหตุสมผลเนื่องจากโครงสร้างได้รับคำสั่งโดยเนื้อแท้ดังนั้นการแบ่งปันชุดข้อมูลจะให้ประโยชน์ที่เป็นไปได้ทั้งหมดโดยอัตโนมัติ
ผลลัพธ์ที่สำคัญคือตรรกะการคิดต้นทุนสำหรับผู้ดำเนินการอัพเดทไม่ได้คำนึงถึงประโยชน์ในการสั่งซื้อนี้ (การส่งเสริม I / O ตามลำดับหรือการปรับให้เหมาะสมอื่น ๆ ) โดยที่วัตถุต้นแบบคือที่เก็บคอลัมน์ นี่เป็นเพราะการปรับเปลี่ยนการจัดเก็บคอลัมน์จะไม่ดำเนินการในสถานที่; พวกเขาใช้ร้านเดลต้า รูปแบบค่าใช้จ่ายจึงสะท้อนให้เห็นถึงความแตกต่างระหว่างการอัพเดตชุด - rowset ที่ใช้ร่วมกันบน b-trees เทียบกับที่เก็บคอลัมน์
อย่างไรก็ตามในกรณีพิเศษของคอลัมน์ที่แบ่งพาร์ติชัน (มาก!) อาจมีประโยชน์ในการสั่งซื้อที่สงวนไว้ในการดำเนินการอัปเดตทั้งหมดไปยังพาร์ติชันหนึ่งก่อนที่จะย้ายไปยังพาร์ติชันถัดไปอาจยังคงได้เปรียบจากมุมมอง I / O .
ตรรกะต้นทุนมาตรฐานจะถูกนำมาใช้ใหม่สำหรับการจัดเก็บคอลัมน์ที่นี่ดังนั้นแผนที่รักษาการสั่งซื้อพาร์ติชัน (แม้ว่าจะไม่ได้สั่งภายในแต่ละพาร์ติชัน) จะมีราคาต่ำกว่า เราสามารถเห็นสิ่งนี้ในแบบสอบถามการทดสอบโดยใช้ค่าสถานะการสืบค้นกลับที่ไม่มีเอกสาร 2332 เพื่อต้องการป้อนข้อมูลที่เรียงลำดับเพื่อดำเนินการปรับปรุง สิ่งนี้ตั้งค่าDMLRequestSort
คุณสมบัติเป็นจริงเมื่อมีการอัพเดตและบังคับให้เครื่องมือเพิ่มประสิทธิภาพสร้างแผนที่จัดเตรียมแถวทั้งหมดสำหรับหนึ่งพาร์ติชันก่อนที่จะย้ายไปยังพาร์ติชันถัดไป:
DELETE Fact.RecordedMetricsDetail
WHERE MeasurementTime < DATEADD(day,-1,GETUTCDATE())
OPTION (RECOMPILE, QUERYTRACEON 2332);
ค่าใช้จ่ายโดยประมาณสำหรับแผนนี้ต่ำกว่ามากมากที่52.5174หน่วย:
การลดต้นทุนนี้เป็นผลมาจากต้นทุน I / O โดยประมาณที่ต่ำกว่าในการอัพเดท Spool ที่แนะนำไม่มีฟังก์ชั่นที่มีประโยชน์ยกเว้นว่ามันจะสามารถรับประกันเอาต์พุตในลำดับของพาร์ติชั่นได้ตามที่ต้องการโดยการอัพเดทด้วยDMLRequestSort = true
(การสแกนอนุกรมของดัชนีที่เก็บคอลัมน์ไม่สามารถรับประกันได้) ค่าใช้จ่ายของสปูลนั้นถือว่าอยู่ในระดับค่อนข้างต่ำโดยเฉพาะอย่างยิ่งเมื่อเทียบกับการลดต้นทุน (ที่อาจไม่สมจริง) ในการอัปเดต
การตัดสินใจว่าจะต้องป้อนข้อมูลตามคำสั่งให้กับผู้ให้บริการอัปเดตนั้นดำเนินการตั้งแต่ต้นในการปรับให้เหมาะสมของแบบสอบถาม ฮิวริสติกที่ใช้ในการตัดสินใจครั้งนี้ไม่เคยมีการบันทึกไว้ แต่สามารถพิจารณาได้จากการลองผิดลองถูก ดูเหมือนว่าขนาดของร้านค้าเดลต้าใด ๆ เป็นข้อมูลป้อนเข้าสำหรับการตัดสินใจนี้ ตัวเลือกนี้จะถาวรสำหรับการรวบรวมแบบสอบถาม จะไม่มีการUSE PLAN
บอกใบ้ให้สำเร็จ: เป้าหมายของแผนนั้นได้สั่งให้ป้อนการอัพเดทหรือไม่
มีวิธีอื่นในการรับแผนต้นทุนต่ำสำหรับการสืบค้นนี้โดยไม่ จำกัด การประเมินความสำคัญของ cardinality การประเมินที่ต่ำเพียงพอเพื่อหลีกเลี่ยง Spool อาจส่งผลให้ DMLRequestSort เป็นเท็จทำให้มีค่าใช้จ่ายตามแผนโดยประมาณสูงมากเนื่องจาก I / O แบบสุ่มที่คาดไว้ อีกทางเลือกหนึ่งคือใช้การตั้งค่าสถานะการสืบค้นกลับ 8649 (แผนขนาน) ร่วมกับ 2332 (DMLRequestSort = true):
DELETE Fact.RecordedMetricsDetail
WHERE MeasurementTime < DATEADD(day,-1,GETUTCDATE())
OPTION (RECOMPILE, QUERYTRACEON 2332, QUERYTRACEON 8649);
สิ่งนี้ส่งผลในแผนที่ใช้การสแกนแบบขนานในแต่ละแบทช์พาร์ติชันและการแลกเปลี่ยนเพื่อรักษา (ผสาน) การรวบรวม Gather Streams:
ขึ้นอยู่กับประสิทธิภาพในการรันของการสั่งซื้อพาร์ติชันบนฮาร์ดแวร์ของคุณสิ่งนี้อาจทำงานได้ดีที่สุดในสามรายการ ที่กล่าวว่าการปรับเปลี่ยนขนาดใหญ่ไม่ใช่ความคิดที่ดีในการจัดเก็บคอลัมน์ดังนั้นแนวคิดการเปลี่ยนพาร์ติชันจึงค่อนข้างดีกว่า หากคุณสามารถรับมือกับเวลาในการรวบรวมที่ยาวนานและตัวเลือกแผนแปลก ๆ มักจะเห็นด้วยวัตถุที่ถูกแบ่งพาร์ติชันโดยเฉพาะอย่างยิ่งเมื่อจำนวนพาร์ติชันมีขนาดใหญ่
การรวมคุณสมบัติที่ค่อนข้างใหม่โดยเฉพาะอย่างยิ่งใกล้ขีด จำกัด ของพวกเขาเป็นวิธีที่ดีในการรับแผนปฏิบัติการที่ไม่ดี ความลึกของการสนับสนุนเครื่องมือเพิ่มประสิทธิภาพมีแนวโน้มที่จะดีขึ้นเมื่อเวลาผ่านไป แต่การใช้งานพาร์ทิชันคอลัมน์จำนวน 15,000 พาร์ติชั่นมักจะหมายถึง
OPTION (QUERYRULEOFF EnforceHPandAccCard)
เก็บพักหายไป ฉันถือว่า HP อาจเป็น "Halloween Protection" แต่แล้วพยายามที่จะใช้แผนการที่มีUSE PLAN
คำใบ้ล้มเหลว (เช่นเดียวกับการพยายามที่จะใช้แผนจากOPTIMIZE FOR
การแก้ปัญหามากเกินไป)