คุณไม่ควรพึ่งพาเปอร์เซ็นต์ค่าใช้จ่ายมากเกินไปในแผนการดำเนินการ ค่าใช้จ่ายเหล่านี้เป็นค่าใช้จ่ายโดยประมาณเสมอแม้ในแผนการดำเนินการภายหลังที่มีหมายเลข 'จริง' สำหรับสิ่งต่าง ๆ เช่นการนับแถว ค่าใช้จ่ายโดยประมาณนั้นขึ้นอยู่กับแบบจำลองที่ทำงานได้ค่อนข้างดีสำหรับจุดประสงค์: เปิดใช้งานเครื่องมือเพิ่มประสิทธิภาพให้เลือกระหว่างแผนการดำเนินการของผู้สมัครที่แตกต่างกันสำหรับแบบสอบถามเดียวกัน ข้อมูลค่าใช้จ่ายน่าสนใจและเป็นปัจจัยที่ควรพิจารณา แต่ไม่ค่อยน่าจะเป็นตัวชี้วัดหลักสำหรับการปรับแต่งแบบสอบถาม การตีความข้อมูลแผนปฏิบัติการจำเป็นต้องมีมุมมองที่กว้างขึ้นของข้อมูลที่นำเสนอ
ItemTran กลุ่มดัชนีแสวงหาผู้ประกอบการ
ตัวดำเนินการนี้มีสองการดำเนินการในหนึ่งเดียว ครั้งแรกที่ดัชนีแสวงหาการดำเนินงานพบว่าทุกแถวที่ตรงกับคำกริยาproduct_code_v42 = 'M10BOLT'
แล้วแต่ละแถวมีกริยาที่เหลือbit_field_v41 & 4 = 0
นำไปใช้ มีการแปลงนัยคือbit_field_v41
จากชนิดฐาน ( tinyint
หรือsmallint
) integer
เพื่อ
การแปลงเกิดขึ้นเนื่องจากตัวดำเนินการbitwise-AND (&) ต้องการให้ตัวถูกดำเนินการทั้งสองเป็นประเภทเดียวกัน ประเภทโดยนัยของค่าคงที่ '4' เป็นจำนวนเต็มและกฎสำคัญกว่าประเภทข้อมูลหมายถึงbit_field_v41
ค่าฟิลด์ที่มีลำดับความสำคัญต่ำกว่าจะถูกแปลง
ปัญหา (เช่นนั้น) สามารถแก้ไขได้อย่างง่ายดายโดยการเขียนภาคแสดงbit_field_v41 & CONVERT(tinyint, 4) = 0
- หมายถึงค่าคงที่มีลำดับความสำคัญต่ำกว่าและถูกแปลง (ระหว่างการพับคงที่) แทนที่จะเป็นค่าคอลัมน์ ถ้าbit_field_v41
เป็นtinyint
ไม่มี Conversion เกิดขึ้นทั้งหมด ในทำนองเดียวกันCONVERT(smallint, 4)
สามารถนำมาใช้ในกรณีที่เป็นbit_field_v41
smallint
ดังกล่าวกล่าวว่าการแปลงไม่ใช่ปัญหาด้านประสิทธิภาพในกรณีนี้ แต่ก็ยังมีแนวปฏิบัติที่ดีในการจับคู่ประเภทและหลีกเลี่ยงการแปลงโดยนัยหากเป็นไปได้
ส่วนใหญ่ของค่าใช้จ่ายโดยประมาณของการค้นหานี้จะลดลงตามขนาดของตารางฐาน ในขณะที่คีย์ดัชนีคลัสเตอร์นั้นแคบพอสมควรขนาดของแต่ละแถวก็ใหญ่ ไม่ได้ให้คำจำกัดความของตาราง แต่มีเพียงคอลัมน์ที่ใช้ในมุมมองเท่านั้นที่เพิ่มความกว้างของแถวที่สำคัญ เนื่องจากดัชนีคลัสเตอร์รวมถึงคอลัมน์ทั้งหมดระยะห่างระหว่างคีย์ดัชนีคลัสเตอร์คือความกว้างของแถวไม่กว้างของดัชนีคีย์ การใช้คำต่อท้ายรุ่นในบางคอลัมน์แสดงให้เห็นว่าตารางจริงมีคอลัมน์มากขึ้นสำหรับรุ่นก่อนหน้า
เมื่อมองไปที่คอลัมน์การค้นหาส่วนที่เหลือและคอลัมน์ผลลัพธ์ประสิทธิภาพของตัวดำเนินการนี้สามารถตรวจสอบได้โดยการสร้างแบบสอบถามที่เทียบเท่า ( 1 <> 2
เป็นกลอุบายเพื่อป้องกันการกำหนดพารามิเตอร์อัตโนมัติความขัดแย้งจะถูกลบโดยเครื่องมือเพิ่มประสิทธิภาพและไม่ปรากฏใน แผนแบบสอบถาม):
SELECT
it.booking_no_v32,
it.QtyCheckedOut,
it.QtyReturned,
it.Trans_qty,
it.trans_type_v41
FROM dbo.tblItemTran AS it
WHERE
1 <> 2
AND it.product_code_v42 = 'M10BOLT'
AND it.bit_field_v41 & CONVERT(tinyint, 4) = 0;
ประสิทธิภาพของแบบสอบถามนี้ด้วยแคชข้อมูลเย็นเป็นที่สนใจเนื่องจากการอ่านล่วงหน้าจะได้รับผลกระทบจากการแตกแฟรกเมนต์ตาราง (ดัชนีคลัสเตอร์) คีย์การทำคลัสเตอร์สำหรับตารางนี้เชิญการแตกแฟรกเมนต์ดังนั้นจึงเป็นสิ่งสำคัญในการบำรุงรักษา (จัดระเบียบใหม่หรือสร้างใหม่) ดัชนีนี้เป็นประจำและใช้ที่เหมาะสมFILLFACTOR
เพื่อให้มีพื้นที่ว่างสำหรับแถวใหม่ระหว่างหน้าต่างการบำรุงรักษาดัชนี
ผมดำเนินการทดสอบผลกระทบของการกระจายตัวบนอ่านล่วงหน้าโดยใช้ข้อมูลตัวอย่างสร้างขึ้นโดยใช้ข้อมูล Generator การใช้แถวตารางเดียวกันจะนับตามที่แสดงในแผนคิวรีของคำถามดัชนีที่กระจัดกระจายอย่างมากทำให้SELECT * FROM view
ใช้เวลา 15 วินาทีหลังจากDBCC DROPCLEANBUFFERS
นั้น การทดสอบเดียวกันในเงื่อนไขเดียวกันกับดัชนีคลัสเตอร์ที่สร้างใหม่สดใหม่บนตาราง ItemTrans เสร็จสมบูรณ์ภายใน 3 วินาที
หากข้อมูลตารางโดยทั่วไปอยู่ในแคชปัญหาการกระจายตัวของข้อมูลมีความสำคัญน้อยกว่ามาก แต่แม้จะมีการกระจายตัวต่ำแถวแถวกว้างอาจหมายถึงจำนวนการอ่านเชิงตรรกะและทางกายภาพสูงกว่าที่คาดไว้มาก นอกจากนี้คุณยังสามารถทดสอบด้วยการเพิ่มและลบคำCONVERT
ชี้แจงออกมาเพื่อตรวจสอบความคาดหวังของฉันว่าปัญหาการแปลงโดยนัยไม่สำคัญที่นี่ยกเว้นเป็นการละเมิดวิธีปฏิบัติที่ดีที่สุด
ยิ่งไปกว่านั้นคือจำนวนแถวโดยประมาณที่ออกจากตัวดำเนินการค้นหา การประเมินเวลาการปรับให้เหมาะสมคือ 165 แถว แต่มีการผลิต 4,226 ครั้งในขณะดำเนินการ ฉันจะกลับมาที่จุดนี้ในภายหลัง แต่เหตุผลหลักสำหรับความคลาดเคลื่อนคือการเลือกของส่วนที่เหลือ (ที่เกี่ยวข้องกับ bitwise-AND) นั้นยากมากสำหรับเครื่องมือเพิ่มประสิทธิภาพในการทำนาย
ผู้ประกอบการตัวกรอง
ฉันกำลังแสดงคำกริยาตัวกรองที่นี่ส่วนใหญ่เพื่อแสดงให้เห็นว่าทั้งสองNOT IN
รายการจะรวมกันง่ายขึ้นและขยายแล้วและยังให้การอ้างอิงสำหรับการอภิปรายการจับคู่แฮชต่อไปนี้ แบบสอบถามทดสอบจากการค้นหาสามารถขยายเพื่อรวมผลกระทบและกำหนดผลกระทบของตัวดำเนินการตัวกรองต่อประสิทธิภาพ:
SELECT
it.booking_no_v32,
it.trans_type_v41,
it.Trans_qty,
it.QtyReturned,
it.QtyCheckedOut
FROM dbo.tblItemTran AS it
WHERE
it.product_code_v42 = 'M10BOLT'
AND it.bit_field_v41 & CONVERT(tinyint, 4) = 0
AND
(
(
it.trans_type_v41 NOT IN (2, 3, 6, 7, 18, 19, 20, 21, 12, 13, 22)
AND it.trans_type_v41 NOT IN (6, 7)
)
OR
(
it.trans_type_v41 NOT IN (6, 7)
)
OR
(
it.trans_type_v41 IN (6, 7)
AND it.QtyCheckedOut = 0
)
OR
(
it.trans_type_v41 IN (6, 7)
AND it.QtyCheckedOut > 0
AND it.trans_qty - (it.QtyCheckedOut - it.QtyReturned) > 0
)
);
ตัวดำเนินการคำนวณสเกลาร์ในแผนกำหนดนิพจน์ต่อไปนี้ (การคำนวณตัวเองถูกเลื่อนออกไปจนกว่าผลลัพธ์จะถูกดำเนินการโดยผู้ดำเนินการภายหลัง)
[Expr1016] = (trans_qty - (QtyCheckedOut - QtyReturned))
ตัวดำเนินการ Hash Match
การเข้าร่วมกับประเภทข้อมูลอักขระไม่ใช่เหตุผลของค่าใช้จ่ายโดยประมาณที่สูงของผู้ให้บริการนี้ คำแนะนำเครื่องมือ SSMS แสดงเฉพาะรายการโพรบ Hash Keys เท่านั้น แต่รายละเอียดที่สำคัญอยู่ในหน้าต่างคุณสมบัติ SSMS
ตัวดำเนินการ Hash Match จะสร้างตารางแฮชโดยใช้ค่าของbooking_no_v32
คอลัมน์ (Hash Keys Build) จากตาราง ItemTran จากนั้นตรวจสอบการจับคู่โดยใช้booking_no
คอลัมน์ (Hash Keys Probe) จากตาราง Bookings คำแนะนำเครื่องมือ SSMS จะแสดง Probe Residual ด้วย แต่ข้อความนั้นยาวเกินไปสำหรับคำแนะนำเครื่องมือและถูกตัดออกไป
Probe Residual คล้ายกับ Residual ที่เห็นหลังจากดัชนีค้นหาก่อนหน้านี้ เพรดิเคตที่เหลือจะถูกประเมินในทุกแถวที่แฮชตรงกันเพื่อกำหนดว่าควรส่งผ่านแถวไปยังโอเปอเรเตอร์หลักหรือไม่ การค้นหาการจับคู่แฮชในตารางแฮชที่มีความสมดุลนั้นเร็วมาก แต่การใช้เพรดิเคตที่ซับซ้อนกับแต่ละแถวที่ตรงกันค่อนข้างช้าโดยการเปรียบเทียบ เคล็ดลับเครื่องมือ Hash Match ใน Plan Explorer แสดงรายละเอียดรวมถึงนิพจน์ที่เหลือของ Probe:
เพรดิเคตที่เหลือมีความซับซ้อนและรวมถึงการตรวจสอบสถานะความคืบหน้าการจองตอนนี้คอลัมน์นั้นพร้อมใช้งานจากตารางจอง เคล็ดลับเครื่องมือยังแสดงความคลาดเคลื่อนที่เหมือนกันระหว่างจำนวนแถวโดยประมาณกับจำนวนแถวจริงที่เห็นก่อนหน้านี้ในการค้นหาดัชนี อาจดูเหมือนว่าการกรองส่วนใหญ่ดำเนินการสองครั้ง แต่นี่เป็นเพียงเครื่องมือเพิ่มประสิทธิภาพเท่านั้นที่มองในแง่ดี ไม่คาดหวังว่าชิ้นส่วนของตัวกรองที่สามารถผลักลงแผนจากหัวตรวจวัดที่เหลือเพื่อกำจัดแถวใด ๆ (การประมาณจำนวนแถวเหมือนกันทั้งก่อนและหลังตัวกรอง) แต่เครื่องมือเพิ่มประสิทธิภาพรู้ว่ามันอาจผิด โอกาสในการกรองแถวก่อน (ลดค่าใช้จ่ายของการเข้าร่วมแฮช) จะคุ้มค่ากับค่าใช้จ่ายเล็กน้อยของตัวกรองพิเศษ ไม่สามารถผลักตัวกรองทั้งหมดลงเนื่องจากมีการทดสอบคอลัมน์จากตารางการจอง แต่ส่วนใหญ่สามารถทำได้
การนับแถวดูถูกดูแคลนเป็นปัญหาสำหรับตัวดำเนินการจับคู่แฮชเนื่องจากจำนวนหน่วยความจำที่สงวนไว้สำหรับตารางแฮชจะขึ้นอยู่กับจำนวนแถวโดยประมาณ ในกรณีที่หน่วยความจำที่มีขนาดเล็กเกินไปสำหรับขนาดของตารางแฮชที่จำเป็นต้องใช้ในเวลาทำงาน (เนื่องจากจำนวนขนาดใหญ่ของแถว) ตารางแฮชซ้ำรั่วไหลทางกายภาพtempdbจัดเก็บข้อมูลมักจะเกิดในประสิทธิภาพที่ดีมาก ในกรณีที่แย่ที่สุดเอ็นจิ้นการประมวลผลจะหยุดการทำแฮ็คถังและรีสอร์ตซ้ำ ๆ เพื่อให้ช้ามากอัลกอริทึม bailout Hash spilling (เรียกซ้ำหรือ bailout) เป็นสาเหตุที่เป็นไปได้มากที่สุดของปัญหาประสิทธิภาพที่ระบุไว้ในคำถาม (ไม่ใช่คอลัมน์เข้าร่วมประเภทตัวอักษรหรือการแปลงโดยนัย) สาเหตุหลักน่าจะเกิดจากเซิร์ฟเวอร์ที่จองหน่วยความจำน้อยเกินไปสำหรับการสืบค้นโดยพิจารณาจากจำนวนแถวที่ไม่ถูกต้อง (cardinality)
น่าเศร้าที่ก่อน SQL Server 2012 ไม่มีข้อบ่งชี้ในแผนการดำเนินการว่าการดำเนินการ hashing เกินกว่าการจัดสรรหน่วยความจำ (ซึ่งไม่สามารถเติบโตแบบไดนามิกหลังจากถูกสงวนไว้ก่อนการดำเนินการเริ่มต้นแม้ว่าเซิร์ฟเวอร์จะมีหน่วยความจำว่างจำนวนมาก) tempdb เป็นไปได้ที่จะตรวจสอบHash Warning Event Classโดยใช้ Profiler แต่มันอาจเป็นเรื่องยากที่จะเชื่อมโยงคำเตือนกับแบบสอบถามเฉพาะ
การแก้ไขปัญหา
ปัญหาสามประการคือการแตกแฟรกเมนต์โพรบที่ซับซ้อนยังคงอยู่ในตัวดำเนินการจับคู่แฮชและการประมาณค่า cardinality ที่ไม่ถูกต้องซึ่งเป็นผลมาจากการคาดเดาที่การค้นหาดัชนี
วิธีแก้ปัญหาที่แนะนำ
ตรวจสอบการแตกแฟรกเมนต์และแก้ไขหากจำเป็นกำหนดเวลาการบำรุงรักษาเพื่อให้แน่ใจว่าดัชนียังคงเป็นที่ยอมรับ วิธีปกติในการแก้ไขค่าประมาณของ cardinality คือการจัดทำสถิติ ในกรณีนี้เครื่องมือเพิ่มประสิทธิภาพต้องมีสถิติสำหรับชุดค่าผสม ( product_code_v42
, bitfield_v41 & 4 = 0
) เราไม่สามารถสร้างสถิติในนิพจน์โดยตรงดังนั้นเราต้องสร้างคอลัมน์จากการคำนวณสำหรับนิพจน์ฟิลด์บิตจากนั้นสร้างสถิติหลายคอลัมน์แบบแมนนวล:
ALTER TABLE dbo.tblItemTran
ADD Bit3 AS bit_field_v41 & CONVERT(tinyint, 4);
CREATE STATISTICS [stats dbo.ItemTran (product_code_v42, Bit3)]
ON dbo.tblItemTran (product_code_v42, Bit3);
คำจำกัดความข้อความคอลัมน์ที่คำนวณต้องตรงกับข้อความในคำจำกัดความมุมมองที่ค่อนข้างตรงกับสถิติที่จะใช้ดังนั้นการแก้ไขมุมมองเพื่อกำจัดการแปลงโดยนัยควรทำในเวลาเดียวกัน
สถิติหลายคอลัมน์ควรส่งผลให้การประเมินดีขึ้นมากลดโอกาสที่ผู้ดำเนินการแข่งขันแฮชจะใช้การหกซ้ำหรืออัลกอริทึม bailout การเพิ่มคอลัมน์ที่คำนวณ (ซึ่งเป็นการดำเนินการเมตาดาต้าเท่านั้นและไม่มีพื้นที่ในตารางเนื่องจากไม่ได้ทำเครื่องหมายPERSISTED
) และสถิติหลายคอลัมน์คือการคาดเดาที่ดีที่สุดสำหรับโซลูชันแรก
เมื่อแก้ไขปัญหาประสิทธิภาพการสืบค้นสิ่งสำคัญคือการวัดสิ่งต่าง ๆ เช่นเวลาที่ผ่านไปการใช้งาน CPU การอ่านแบบลอจิคัลการอ่านแบบฟิสิคัลชนิดการรอและระยะเวลา ... และอื่น ๆ นอกจากนี้ยังมีประโยชน์ในการเรียกใช้บางส่วนของแบบสอบถามแยกต่างหากเพื่อตรวจสอบสาเหตุที่น่าสงสัยดังที่แสดงด้านบน
ในบางสภาพแวดล้อมที่การดูข้อมูลที่ไม่เป็นปัจจุบันนั้นมีความสำคัญอาจเป็นประโยชน์ในการเรียกใช้กระบวนการพื้นหลังที่ทำให้มุมมองทั้งหมดเป็นภาพรวมในตารางสแน็ปช็อตบ่อยครั้ง ตารางนี้เป็นเพียงตารางพื้นฐานปกติและสามารถสร้างดัชนีสำหรับแบบสอบถามแบบอ่านได้โดยไม่ต้องกังวลกับผลกระทบของประสิทธิภาพการอัปเดต
ดูการจัดทำดัชนี
อย่าล่อลวงให้ทำดัชนีมุมมองดั้งเดิมโดยตรง ประสิทธิภาพการอ่านจะเร็วอย่างน่าอัศจรรย์ (การค้นหาเพียงครั้งเดียวในดัชนีมุมมอง) แต่ (ในกรณีนี้) ปัญหาประสิทธิภาพทั้งหมดในแผนแบบสอบถามที่มีอยู่จะถูกถ่ายโอนไปยังแบบสอบถามที่ปรับเปลี่ยนคอลัมน์ตารางใด ๆ ที่อ้างอิงในมุมมอง คำค้นหาที่เปลี่ยนแถวตารางพื้นฐานจะได้รับผลกระทบไม่ดีอย่างแน่นอน
โซลูชันขั้นสูงพร้อมมุมมองที่จัดทำดัชนีไว้บางส่วน
มีวิธีแก้ปัญหาการดูดัชนีบางส่วนสำหรับการสืบค้นนี้โดยเฉพาะที่แก้ไขการประมาณเชิงลบและลบตัวกรองและโพรบส่วนที่เหลือ แต่ขึ้นอยู่กับสมมติฐานบางอย่างเกี่ยวกับข้อมูล ดัชนีเพื่อสนับสนุนแผนการบำรุงรักษามุมมองที่จัดทำดัชนี ฉันแบ่งปันรหัสด้านล่างเพื่อความสนใจฉันไม่เสนอให้คุณนำไปใช้โดยไม่มีการวิเคราะห์และทดสอบอย่างระมัดระวัง
-- Indexed view to optimize the main view
CREATE VIEW dbo.V1
WITH SCHEMABINDING
AS
SELECT
it.ID,
it.product_code_v42,
it.trans_type_v41,
it.booking_no_v32,
it.Trans_qty,
it.QtyReturned,
it.QtyCheckedOut,
it.QtyReserved,
it.bit_field_v41,
it.prep_on,
it.From_locn,
it.Trans_to_locn,
it.PDate,
it.FirstDate,
it.PTimeH,
it.PTimeM,
it.RetnDate,
it.BookDate,
it.TimeBookedH,
it.TimeBookedM,
it.TimeBookedS,
it.del_time_hour,
it.del_time_min,
it.return_to_locn,
it.return_time_hour,
it.return_time_min,
it.AssignTo,
it.AssignType,
it.InRack
FROM dbo.tblItemTran AS it
JOIN dbo.tblBookings AS tb ON
tb.booking_no = it.booking_no_v32
WHERE
(
it.trans_type_v41 NOT IN (2, 3, 7, 18, 19, 20, 21, 12, 13, 22)
AND it.trans_type_v41 NOT IN (6, 7)
AND it.bit_field_v41 & CONVERT(tinyint, 4) = 0
)
OR
(
it.trans_type_v41 NOT IN (6, 7)
AND it.bit_field_v41 & CONVERT(tinyint, 4) = 0
AND tb.BookingProgressStatus = 1
)
OR
(
it.trans_type_v41 IN (6, 7)
AND it.bit_field_v41 & CONVERT(tinyint, 4) = 0
AND it.QtyCheckedOut = 0
)
OR
(
it.trans_type_v41 IN (6, 7)
AND it.bit_field_v41 & CONVERT(tinyint, 4) = 0
AND it.QtyCheckedOut > 0
AND it.trans_qty - (it.QtyCheckedOut - it.QtyReturned) > 0
);
GO
CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.V1 (product_code_v42, ID);
GO
มุมมองที่มีอยู่ tweaked เพื่อใช้มุมมองที่จัดทำดัชนีด้านบน:
CREATE VIEW [dbo].[vwReallySlowView2]
AS
SELECT
I.booking_no_v32 AS bkno,
I.trans_type_v41 AS trantype,
B.Assigned_to_v61 AS Assignbk,
B.order_date AS dateo,
B.HourBooked AS HBooked,
B.MinBooked AS MBooked,
B.SecBooked AS SBooked,
I.prep_on AS Pon,
I.From_locn AS Flocn,
I.Trans_to_locn AS TTlocn,
CASE I.prep_on
WHEN 'Y' THEN I.PDate
ELSE I.FirstDate
END AS PrDate,
I.PTimeH AS PrTimeH,
I.PTimeM AS PrTimeM,
CASE
WHEN I.RetnDate < I.FirstDate
THEN I.FirstDate
ELSE I.RetnDate
END AS RDatev,
I.bit_field_v41 AS bitField,
I.FirstDate AS FDatev,
I.BookDate AS DBooked,
I.TimeBookedH AS TBookH,
I.TimeBookedM AS TBookM,
I.TimeBookedS AS TBookS,
I.del_time_hour AS dth,
I.del_time_min AS dtm,
I.return_to_locn AS rtlocn,
I.return_time_hour AS rth,
I.return_time_min AS rtm,
CASE
WHEN
I.Trans_type_v41 IN (6, 7)
AND I.Trans_qty < I.QtyCheckedOut
THEN 0
WHEN
I.Trans_type_v41 IN (6, 7)
AND I.Trans_qty >= I.QtyCheckedOut
THEN I.Trans_Qty - I.QtyCheckedOut
ELSE
I.trans_qty
END AS trqty,
CASE
WHEN I.Trans_type_v41 IN (6, 7)
THEN 0
ELSE I.QtyCheckedOut
END AS MyQtycheckedout,
CASE
WHEN I.Trans_type_v41 IN (6, 7)
THEN 0
ELSE I.QtyReturned
END AS retqty,
I.ID,
B.BookingProgressStatus AS bkProg,
I.product_code_v42,
I.return_to_locn,
I.AssignTo,
I.AssignType,
I.QtyReserved,
B.DeprepOn,
CASE B.DeprepOn
WHEN 1 THEN B.DeprepDateTime
ELSE I.RetnDate
END AS DeprepDateTime,
I.InRack
FROM dbo.V1 AS I WITH (NOEXPAND)
JOIN dbo.tblbookings AS B ON
B.booking_no = I.booking_no_v32
JOIN dbo.tblInvmas AS M ON
I.product_code_v42 = M.product_code;
ตัวอย่างแบบสอบถามและแผนการดำเนินการ:
SELECT
vrsv.*
FROM dbo.vwReallySlowView2 AS vrsv
WHERE vrsv.product_code_v42 = 'M10BOLT';
ในแผนใหม่การแข่งขันกัญชามีไม่มีกริยาที่เหลือมีไม่มีตัวกรองที่ซับซ้อน , ไม่มีกริยาที่เหลือในมุมมองการจัดทำดัชนีแสวงหาและประมาณการ cardinalityถูกต้องว่า
เป็นตัวอย่างของวิธีการที่แทรก / ปรับปรุง / ลบแผนจะได้รับผลกระทบนี่คือแผนสำหรับการแทรกไปยังตาราง ItemTrans:
ส่วนที่ไฮไลต์เป็นของใหม่และจำเป็นสำหรับการบำรุงรักษามุมมองที่จัดทำดัชนี สปูลรีเพลย์จะแทรกแถวตารางพื้นฐานสำหรับการบำรุงรักษามุมมองที่จัดทำดัชนีไว้ แต่ละแถวจะถูกรวมเข้ากับตารางการจองโดยใช้การค้นหาดัชนีแบบกลุ่มจากนั้นตัวกรองจะใช้ส่วนWHERE
คำสั่งที่ซับซ้อนเพื่อดูว่าจำเป็นต้องเพิ่มแถวในมุมมองหรือไม่ ถ้าเป็นเช่นนั้นการแทรกจะดำเนินการกับดัชนีคลัสเตอร์ของมุมมอง
การSELECT * FROM view
ทดสอบเดียวกันเสร็จสมบูรณ์ก่อนหน้านี้ใน 150ms โดยมีมุมมองที่ทำดัชนีไว้
สิ่งสุดท้าย: ฉันสังเกตเห็นว่าเซิร์ฟเวอร์ 2008 R2 ของคุณยังอยู่ที่ RTM มันจะไม่แก้ไขปัญหาประสิทธิภาพการทำงานของคุณ แต่Service Pack 2 สำหรับ 2008 R2พร้อมใช้งานตั้งแต่เดือนกรกฎาคม 2012 และมีเหตุผลที่ดีมากมายที่จะทำให้เป็นปัจจุบันที่สุดเท่าที่จะทำได้ด้วย Service Pack