นี่เป็นข้อผิดพลาดใน SQL Server (รวมตั้งแต่ปี 2008 ถึงปี 2014)
รายงานข้อผิดพลาดของฉันคือที่นี่
เงื่อนไขการกรองจะถูกผลักลงไปในผู้ประกอบการสแกนเป็นกริยาที่เหลือ แต่ความทรงจำที่ได้รับสำหรับการจัดเรียงที่มีการคำนวณอย่างไม่ถูกต้องอยู่บนพื้นฐานของการประมาณการ cardinality กรองก่อน
เพื่อแสดงปัญหาเราสามารถใช้การตั้งค่าสถานะการสืบค้นกลับ(ที่ไม่มีเอกสารและไม่สนับสนุน) 9130 เพื่อป้องกันไม่ให้ตัวกรองถูกส่งลงไปยังผู้ดำเนินการสแกน ขณะนี้หน่วยความจำที่ให้กับการเรียงลำดับถูกต้องขึ้นอยู่กับ cardinality โดยประมาณของเอาต์พุต Filter ไม่ใช่การสแกน:
SELECT
T.TID,
T.FilterMe,
T.SortMe,
T.Unused
FROM dbo.Test AS T
WHERE
T.FilterMe = 567
ORDER BY
T.SortMe
OPTION (QUERYTRACEON 9130); -- Not for production systems!
สำหรับระบบที่ใช้งานจริงจะต้องดำเนินการตามขั้นตอนต่างๆเพื่อหลีกเลี่ยงรูปร่างของปัญหาที่มีปัญหา (ตัวกรองถูกผลักเข้าไปในการสแกนพร้อมจัดเรียงคอลัมน์อื่น) วิธีหนึ่งในการทำเช่นนี้คือการจัดทำดัชนีเกี่ยวกับเงื่อนไขตัวกรองและ / หรือเพื่อจัดลำดับการเรียงที่ต้องการ
-- Index on the filter condition only
CREATE NONCLUSTERED INDEX IX_dbo_Test_FilterMe
ON dbo.Test (FilterMe);
เมื่อใช้ดัชนีนี้การจัดสรรหน่วยความจำที่ต้องการสำหรับการเรียงลำดับมีเพียง928KB :
การเพิ่มเติมดัชนีต่อไปนี้สามารถหลีกเลี่ยงการเรียงลำดับได้อย่างสมบูรณ์ ( ไม่มีหน่วยความจำให้):
-- Provides filtering and sort order
-- nvarchar(max) column deliberately not INCLUDEd
CREATE NONCLUSTERED INDEX IX_dbo_Test_FilterMe_SortMe
ON dbo.Test (FilterMe, SortMe);
ทดสอบและบั๊กที่ยืนยันในบิลด์ต่อไปนี้ของ SQL Server x64 Developer Edition:
2014 : 12.00.2430 (RTM CU4)
2012 : 11.00.5556 (SP2 CU3)
2008R2 : 10.50.6000 (SP3)
2008 : 10.00.6000 (SP4)
นี้ได้รับการแก้ไขในSQL Server 2016 Service Pack 1 บันทึกย่อประจำรุ่นประกอบด้วย:
หมายเลขข้อผิดพลาด VSTS 8024987 การ
สแกนตารางและการสแกนดัชนีด้วยภาคแสดงแบบเลื่อนลงมีแนวโน้มที่จะประเมินค่าหน่วยความจำมากเกินไปสำหรับผู้ให้บริการหลัก
ผ่านการทดสอบและยืนยันแล้วเมื่อ:
Microsoft SQL Server 2016 (SP1) - 13.0.4001.0 (X64) Developer Edition
Microsoft SQL Server 2014 (SP2-CU3) 12.0.5538.0 (X64) Developer Edition
ทั้งรุ่น CE