พิจารณาแบบสอบถามต่อไปนี้ที่แทรกแถวจากตารางต้นฉบับเฉพาะเมื่อยังไม่ได้อยู่ในตารางเป้าหมาย:
INSERT INTO dbo.HALLOWEEN_IS_COMING_EARLY_THIS_YEAR WITH (TABLOCK)
SELECT maybe_new_rows.ID
FROM dbo.A_HEAP_OF_MOSTLY_NEW_ROWS maybe_new_rows
WHERE NOT EXISTS (
SELECT 1
FROM dbo.HALLOWEEN_IS_COMING_EARLY_THIS_YEAR halloween
WHERE maybe_new_rows.ID = halloween.ID
)
OPTION (MAXDOP 1, QUERYTRACEON 7470);
รูปร่างแผนหนึ่งที่เป็นไปได้รวมถึงการรวมการผสานและสปูลที่กระตือรือร้น ผู้ประกอบการสปูลกระตือรือร้นที่จะนำเสนอเพื่อแก้ปัญหาฮาโลวีน :
บนเครื่องของฉันรหัสด้านบนจะทำงานในเวลาประมาณ 6900 มิลลิวินาที รหัส Repro เพื่อสร้างตารางรวมอยู่ที่ด้านล่างของคำถาม หากฉันไม่พอใจกับการแสดงฉันอาจลองโหลดแถวเพื่อแทรกลงในตารางชั่วคราวแทนการใช้สปูลกระตือรือร้น การดำเนินการหนึ่งที่เป็นไปได้มีดังนี้:
DROP TABLE IF EXISTS #CONSULTANT_RECOMMENDED_TEMP_TABLE;
CREATE TABLE #CONSULTANT_RECOMMENDED_TEMP_TABLE (
ID BIGINT,
PRIMARY KEY (ID)
);
INSERT INTO #CONSULTANT_RECOMMENDED_TEMP_TABLE WITH (TABLOCK)
SELECT maybe_new_rows.ID
FROM dbo.A_HEAP_OF_MOSTLY_NEW_ROWS maybe_new_rows
WHERE NOT EXISTS (
SELECT 1
FROM dbo.HALLOWEEN_IS_COMING_EARLY_THIS_YEAR halloween
WHERE maybe_new_rows.ID = halloween.ID
)
OPTION (MAXDOP 1, QUERYTRACEON 7470);
INSERT INTO dbo.HALLOWEEN_IS_COMING_EARLY_THIS_YEAR WITH (TABLOCK)
SELECT new_rows.ID
FROM #CONSULTANT_RECOMMENDED_TEMP_TABLE new_rows
OPTION (MAXDOP 1);
รหัสใหม่รันในประมาณ 4400 มิลลิวินาที ฉันสามารถรับแผนจริงและใช้สถิติเวลาจริงเพื่อตรวจสอบเวลาที่ใช้ในระดับผู้ปฏิบัติงาน โปรดทราบว่าการขอแผนจริงเพิ่มค่าใช้จ่ายที่สำคัญสำหรับคิวรีเหล่านี้ดังนั้นผลรวมจะไม่ตรงกับผลลัพธ์ก่อนหน้า
╔═════════════╦═════════════╦══════════════╗
║ operator ║ first query ║ second query ║
╠═════════════╬═════════════╬══════════════╣
║ big scan ║ 1771 ║ 1744 ║
║ little scan ║ 163 ║ 166 ║
║ sort ║ 531 ║ 530 ║
║ merge join ║ 709 ║ 669 ║
║ spool ║ 3202 ║ N/A ║
║ temp insert ║ N/A ║ 422 ║
║ temp scan ║ N/A ║ 187 ║
║ insert ║ 3122 ║ 1545 ║
╚═════════════╩═════════════╩══════════════╝
แผนคิวรีที่มีสปูลกระตือรือร้นดูเหมือนจะใช้เวลากับตัวดำเนินการแทรกและสปูลอย่างมีนัยสำคัญเมื่อเปรียบเทียบกับแผนที่ใช้ตารางชั่วคราว
เหตุใดแผนการที่มีตารางอุณหภูมิจึงมีประสิทธิภาพมากกว่า Spool ที่กระตือรือร้นไม่ใช่ส่วนใหญ่เป็นเพียงตารางอุณหภูมิภายในใช่หรือไม่ ฉันเชื่อว่าฉันกำลังมองหาคำตอบที่มุ่งเน้นไปที่ internals ฉันสามารถดูว่าสแต็คการโทรแตกต่างกันอย่างไร แต่ไม่สามารถเข้าใจภาพรวมได้
ฉันใช้ SQL Server 2017 CU 11 ในกรณีที่มีคนต้องการทราบ นี่คือรหัสในการเติมตารางที่ใช้ในการสืบค้นด้านบน:
DROP TABLE IF EXISTS dbo.HALLOWEEN_IS_COMING_EARLY_THIS_YEAR;
CREATE TABLE dbo.HALLOWEEN_IS_COMING_EARLY_THIS_YEAR (
ID BIGINT NOT NULL,
PRIMARY KEY (ID)
);
INSERT INTO dbo.HALLOWEEN_IS_COMING_EARLY_THIS_YEAR WITH (TABLOCK)
SELECT TOP (20000000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values t1
CROSS JOIN master..spt_values t2
CROSS JOIN master..spt_values t3
OPTION (MAXDOP 1);
DROP TABLE IF EXISTS dbo.A_HEAP_OF_MOSTLY_NEW_ROWS;
CREATE TABLE dbo.A_HEAP_OF_MOSTLY_NEW_ROWS (
ID BIGINT NOT NULL
);
INSERT INTO dbo.A_HEAP_OF_MOSTLY_NEW_ROWS WITH (TABLOCK)
SELECT TOP (1900000) 19999999 + ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;