นี่เป็นข้อบกพร่องของ SQL Server 2016 หรือไม่
ใช่. แน่นอนว่านี่ไม่ใช่พฤติกรรมที่ถูกต้อง ผมได้มีการรายงานได้ที่นี่และมีการแก้ไขใน SQL Server 2016 SP2 CU9
ดังที่Mikael Erikssonกล่าวไว้ในความคิดเห็นsys.database_scoped_configurations
และsys.dm_exec_sessions
นำไปใช้เป็นมุมมองในรูปแบบ
SELECT ...
FROM OpenRowset(TABLE xxxx)
อย่างไรก็ตามการเปรียบเทียบทั้งสองแผนด้านล่างมีความแตกต่างที่ชัดเจน
DBCC TRACEON(3604);
DECLARE @database_scoped_configurations TABLE(x INT);
INSERT INTO @database_scoped_configurations
SELECT configuration_id
FROM sys.database_scoped_configurations
OPTION (QUERYTRACEON 8608, QUERYTRACEON 8615, QUERYTRACEON 8619, QUERYTRACEON 8620 );
DECLARE @dm_exec_sessions TABLE(x INT);
INSERT INTO @dm_exec_sessions
SELECT session_id
FROM sys.dm_exec_sessions
OPTION (QUERYTRACEON 8608, QUERYTRACEON 8615, QUERYTRACEON 8619, QUERYTRACEON 8620 );
ผลลัพธ์การติดตามสถานะ 8619 สำหรับแบบสอบถามทั้งสองนี้แสดง
ใช้กฎ: EnforceHPandAccCard - x0-> Spool หรือ Top (x0)
เห็นได้ชัดว่า SQL Server ไม่สามารถยืนยันได้ว่าแหล่งที่มาสำหรับ TVF นั้นไม่ใช่เป้าหมายการแทรกดังนั้นจึงต้องมีการป้องกันฮาโลวีน
ในกรณีเซสชันนี้ถูกนำมาใช้เป็นสปูลที่รวบรวมแถวทั้งหมดก่อน ในการdatabase_scoped_configurations
โดยการเพิ่มTOP 1
แผน การใช้TOP
สำหรับการป้องกันฮาโลวีนที่กำลังจะกล่าวถึงในบทความนี้ บทความนี้ยังกล่าวถึงค่าสถานะการสืบค้นกลับที่ไม่มีเอกสารเพื่อบังคับให้สปูลแทนที่จะTOP
ทำงานตามที่คาดไว้
DECLARE @database_scoped_configurations TABLE(x INT);
INSERT INTO @database_scoped_configurations
SELECT configuration_id
FROM sys.database_scoped_configurations
OPTION (QUERYTRACEON 8692)
ปัญหาที่ชัดเจนเกี่ยวกับการใช้TOP 1
แทนที่จะเก็บพักคือว่ามันจะ จำกัด จำนวนแถวที่ใส่เข้าไปโดยพลการ ดังนั้นนี่จะถูกต้องถ้าจำนวนแถวที่ส่งคืนโดยฟังก์ชันคือ <= 1
บันทึกเริ่มต้นมีลักษณะเช่นนี้
เปรียบเทียบสิ่งนี้กับบันทึกเริ่มต้นสำหรับแบบสอบถาม 2
หากฉันเข้าใจอย่างถูกต้องข้างต้นก็คิดว่า TVF แรกสามารถส่งคืนได้สูงสุดหนึ่งแถวและใช้การเพิ่มประสิทธิภาพที่ไม่ถูกต้อง Max สำหรับแบบสอบถามที่สองถูกตั้งค่าเป็น1.34078E+154
( 2^512
)
ฉันไม่ทราบว่ามาจาก rowcount สูงสุดนี้มาจากไหน บางทีข้อมูลเมตาที่จัดทำโดยผู้เขียน DMV? มันก็แปลกที่TOP(50)
วิธีแก้ปัญหาไม่ได้รับการเขียนใหม่TOP(1)
เพราะTOP(50)
จะไม่ป้องกันปัญหาฮาโลวีนเกิดขึ้น (แม้ว่าจะหยุดมันต่อไปเรื่อย ๆ )