มันค่อนข้างกว้าง แต่ฉันคิดว่าฉันเข้าใจคำถามที่แท้จริงและจะตอบตามนั้น แค่พูดถึง table vs index spool ฉันไม่คิดว่ามันค่อนข้างถูกต้องที่จะดูว่าเป็นตัวเลือกระหว่างตารางและดัชนีสปูล อย่างที่คุณทราบมันเป็นไปได้ในทรีย่อยเดียวเพื่อรับดัชนีสปูลสปูลตารางหรือทั้งสปูลดัชนีและสปูลตาราง ฉันเชื่อว่าถูกต้องแล้วที่จะบอกว่าคุณได้รับสปูลดัชนีภายใต้เงื่อนไขต่อไปนี้:
- เครื่องมือเพิ่มประสิทธิภาพคิวรีมีเหตุผลในการแปลงการเข้าร่วมเป็นการใช้
- เครื่องมือเพิ่มประสิทธิภาพแบบสอบถามทำการแปลงไปใช้จริง
- เครื่องมือเพิ่มประสิทธิภาพคิวรีใช้กฎเพื่อเพิ่มสปูลดัชนี (อย่างน้อยสปูลดัชนีจะต้องปลอดภัยที่จะใช้)
- เลือกแผนการด้วยดัชนีสปูล
คุณสามารถดูสิ่งเหล่านี้ได้ด้วยการสาธิตง่ายๆ เริ่มต้นด้วยการสร้างฮีปหนึ่งคู่:
DROP TABLE IF EXISTS dbo.X_10000_VARCHAR_901;
CREATE TABLE dbo.X_10000_VARCHAR_901 (ID VARCHAR(901) NOT NULL);
INSERT INTO dbo.X_10000_VARCHAR_901 WITH (TABLOCK)
SELECT TOP (10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;
DROP TABLE IF EXISTS dbo.X_10000_VARCHAR_800;
CREATE TABLE dbo.X_10000_VARCHAR_800 (ID VARCHAR(800) NOT NULL);
INSERT INTO dbo.X_10000_VARCHAR_800 WITH (TABLOCK)
SELECT TOP (10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;
สำหรับคำถามแรกไม่มีอะไรให้ค้นหา:
SELECT *
FROM dbo.X_10000_VARCHAR_901 a
CROSS JOIN dbo.X_10000_VARCHAR_901 b
OPTION (MAXDOP 1);
ดังนั้นจึงไม่มีเหตุผลที่เครื่องมือเพิ่มประสิทธิภาพจะเปลี่ยนการเข้าร่วมเป็นการสมัคร คุณลงเอยด้วยสปูลโต๊ะเนื่องจากเหตุผลด้านการคิดต้นทุน ดังนั้นแบบสอบถามนี้จึงล้มเหลวในการทดสอบครั้งแรก
สำหรับข้อความค้นหาถัดไปมีความเป็นธรรมที่คาดว่าเครื่องมือเพิ่มประสิทธิภาพมีเหตุผลในการพิจารณาใช้:
SELECT *
FROM dbo.X_10000_VARCHAR_901 a
INNER JOIN dbo.X_10000_VARCHAR_901 b ON a.ID = b.ID
OPTION (LOOP JOIN, MAXDOP 1);
แต่มันไม่ได้หมายความว่าจะเป็น:
แบบสอบถามนี้ล้มเหลวในการทดสอบครั้งที่สอง คำอธิบายที่สมบูรณ์ที่นี่ การอ้างอิงส่วนที่เกี่ยวข้องมากที่สุด:
เครื่องมือเพิ่มประสิทธิภาพจะไม่พิจารณาสร้างดัชนีทันทีเพื่อให้สามารถใช้งานได้ ค่อนข้างลำดับของเหตุการณ์มักจะเป็นสิ่งที่ตรงกันข้าม: แปลงเพื่อนำไปใช้เพราะมีดัชนีที่ดีอยู่
ฉันสามารถเขียนคำถามเพื่อส่งเสริมให้เครื่องมือเพิ่มประสิทธิภาพพิจารณาใช้:
SELECT *
FROM dbo.X_10000_VARCHAR_901 a
INNER JOIN dbo.X_10000_VARCHAR_901 b ON a.ID >= b.ID AND a.ID <= b.ID
OPTION (MAXDOP 1);
แต่ยังไม่มีดัชนีสปูล:
แบบสอบถามนี้ล้มเหลวในการทดสอบครั้งที่สาม ใน SQL Server 2014 มีการจำกัดความยาวของคีย์ดัชนี 900 ไบต์ สิ่งนี้ได้รับการขยายใน SQL Server 2016 แต่สำหรับดัชนีที่ไม่ใช่คลัสเตอร์เท่านั้น ดัชนีสปูเป็นดัชนีคลัสเตอร์เพื่อให้วงเงินที่ยังคงอยู่ที่ 900 ไบต์ ไม่ว่าในกรณีใดกฎสปูลดัชนีไม่สามารถใช้ได้เนื่องจากอาจนำไปสู่ข้อผิดพลาดในระหว่างการดำเนินการค้นหา
การลดความยาวของชนิดข้อมูลเป็น 800 ในที่สุดก็ให้แผนด้วยสปูลดัชนี:
แผนสปูลดัชนีไม่น่าแปลกใจที่มีราคาถูกกว่าแผนอย่างไม่มีสปูล: 89.7603 หน่วยเทียบกับ 598.832 หน่วย คุณสามารถเห็นความแตกต่างด้วยQUERYRULEOFF BuildSpool
คำใบ้ที่ไม่มีเอกสาร:
นี่ไม่ใช่คำตอบที่สมบูรณ์ แต่หวังว่าจะเป็นสิ่งที่คุณกำลังมองหา