คำถามของคุณแสดงให้เห็นว่าคุณได้เข้าใจผิดเกี่ยวกับตัวแปรตารางและตารางชั่วคราว
ฉันได้เขียนคำตอบมากมายในเว็บไซต์ DBA เพื่อดูความแตกต่างระหว่างสองประเภทของวัตถุ สิ่งนี้ยังตอบคำถามของคุณเกี่ยวกับดิสก์ vs หน่วยความจำ (ฉันไม่เห็นความแตกต่างอย่างมีนัยสำคัญระหว่างพฤติกรรมทั้งสอง)
เกี่ยวกับคำถามในชื่อเรื่องว่าเมื่อใดควรใช้ตัวแปรตารางเทียบกับตารางชั่วคราวในตัวคุณจะไม่มีทางเลือก ในฟังก์ชั่นเช่นมันเป็นไปได้ที่จะใช้ตัวแปรตารางและถ้าคุณจำเป็นต้องเขียนลงในตารางในขอบเขตเด็กแล้วเพียงแค่#temp
ตารางที่จะทำ (พารามิเตอร์ที่มีมูลค่าของตารางอนุญาตการเข้าถึงแบบอ่านอย่างเดียว )
ที่คุณมีตัวเลือกคำแนะนำอยู่ด้านล่าง (แม้ว่าวิธีการที่เชื่อถือได้ที่สุดก็คือการทดสอบทั้งกับภาระงานเฉพาะของคุณ)
หากคุณต้องการดัชนีที่ไม่สามารถสร้างบนตัวแปรตารางได้แน่นอนคุณจะต้องมี#temporary
ตาราง รายละเอียดของรุ่นนี้ขึ้นอยู่กับรุ่นอย่างไรก็ตาม สำหรับ SQL Server 2012 และต่ำกว่าดัชนีเท่านั้นที่สามารถสร้างขึ้นได้ในตัวแปรตารางคือสิ่งที่สร้างโดยนัยผ่านทางUNIQUE
หรือPRIMARY KEY
ข้อ จำกัด SQL Server 2014 CREATE INDEX
แนะนำไวยากรณ์ดัชนีอินไลน์สำหรับย่อยของในตัวเลือกที่มีอยู่ สิ่งนี้ได้รับการขยายตั้งแต่เพื่ออนุญาตเงื่อนไขดัชนีที่กรองแล้ว ดัชนีที่มีINCLUDE
คอลัมน์ -d หรือดัชนี columnstore ยังไม่สามารถสร้างบนตัวแปรตารางได้
หากคุณจะเพิ่มและลบแถวจำนวนมากซ้ำ ๆ จากตารางให้ใช้#temporary
ตาราง ที่สนับสนุนTRUNCATE
(ซึ่งจะมีประสิทธิภาพมากกว่าDELETE
สำหรับตารางขนาดใหญ่) และยังแทรกตามมาต่อไปนี้TRUNCATE
จะมีประสิทธิภาพที่ดีขึ้นกว่าที่ดังต่อไปนี้เป็นที่แสดงที่นี่DELETE
- หากคุณจะลบหรืออัปเดตแถวจำนวนมากตาราง temp อาจทำงานได้ดีกว่าตัวแปรตาราง - หากสามารถใช้การแชร์ rowset ได้ (ดู "ผลของการแชร์ rowset" ด้านล่าง)
- หากแผนที่ดีที่สุดโดยใช้ตารางจะแตกต่างกันไปขึ้นอยู่กับข้อมูลจากนั้นใช้
#temporary
ตาราง ที่รองรับการสร้างสถิติซึ่งช่วยให้แผนสามารถคอมไพล์ใหม่แบบไดนามิกตามข้อมูล (แม้ว่าสำหรับแคชชั่วคราวตารางในกระบวนงานที่เก็บไว้พฤติกรรมการคอมไพล์ซ้ำจะต้องเข้าใจแยกต่างหาก)
- หากแผนที่ดีที่สุดสำหรับแบบสอบถามที่ใช้ตารางไม่น่าจะเปลี่ยนแปลงคุณอาจพิจารณาตัวแปรตารางเพื่อข้ามค่าใช้จ่ายในการสร้างสถิติและคอมไพล์ซ้ำ (อาจต้องมีคำแนะนำเพื่อแก้ไขแผนที่คุณต้องการ)
- หากแหล่งข้อมูลที่แทรกลงในตารางนั้นมาจาก
SELECT
คำแถลงที่อาจมีราคาแพงให้พิจารณาว่าการใช้ตัวแปรตารางจะป้องกันความเป็นไปได้ของสิ่งนี้โดยใช้แผนคู่ขนาน
- ถ้าคุณต้องการข้อมูลในตารางเพื่อเอาตัวรอดการย้อนกลับของธุรกรรมผู้ใช้ภายนอกจากนั้นใช้ตัวแปรตาราง กรณีการใช้งานที่เป็นไปได้สำหรับกรณีนี้อาจเป็นการบันทึกความคืบหน้าของขั้นตอนต่าง ๆ ในชุดงาน SQL แบบยาว
- เมื่อใช้
#temp
ตารางภายในล็อกธุรกรรมผู้ใช้สามารถจัดขึ้นนานกว่าสำหรับตัวแปรตาราง (อาจจนกว่าจะสิ้นสุดของการทำธุรกรรม VS ท้ายของคำสั่งขึ้นอยู่กับชนิดของล็อคและระดับแยก) และยังสามารถป้องกันการตัดของtempdb
ล็อกธุรกรรมจนกว่า การทำธุรกรรมของผู้ใช้จะสิ้นสุดลง ดังนั้นสิ่งนี้อาจสนับสนุนการใช้ตัวแปรตาราง
- ภายในรูทีนที่เก็บไว้ทั้งตัวแปรตารางและตารางชั่วคราวสามารถแคชได้ การบำรุงรักษาข้อมูลเมตาสำหรับตัวแปรตารางแคชน้อยกว่าสำหรับ
#temporary
ตาราง บ๊อบวอร์ดชี้ให้เห็นในtempdb
การนำเสนอของเขาว่าสิ่งนี้อาจทำให้เกิดการโต้แย้งเพิ่มเติมในตารางระบบภายใต้เงื่อนไขของการเกิดพร้อมกันสูง นอกจากนี้เมื่อต้องรับมือกับปริมาณขนาดเล็กของข้อมูลนี้สามารถทำให้ความแตกต่างที่สามารถวัดประสิทธิภาพการทำงาน
ผลกระทบของการแบ่งปัน rowset
DECLARE @T TABLE(id INT PRIMARY KEY, Flag BIT);
CREATE TABLE #T (id INT PRIMARY KEY, Flag BIT);
INSERT INTO @T
output inserted.* into #T
SELECT TOP 1000000 ROW_NUMBER() OVER (ORDER BY @@SPID), 0
FROM master..spt_values v1, master..spt_values v2
SET STATISTICS TIME ON
/*CPU time = 7016 ms, elapsed time = 7860 ms.*/
UPDATE @T SET Flag=1;
/*CPU time = 6234 ms, elapsed time = 7236 ms.*/
DELETE FROM @T
/* CPU time = 828 ms, elapsed time = 1120 ms.*/
UPDATE #T SET Flag=1;
/*CPU time = 672 ms, elapsed time = 980 ms.*/
DELETE FROM #T
DROP TABLE #T
tempDB
- ว่า "ในหน่วยความจำ" เป็นตำนาน นอกจากนี้: ตัวแปรตารางจะได้รับการพิจารณาโดยเครื่องมือเพิ่มประสิทธิภาพคิวรีเพื่อเก็บแถวหนึ่งไว้อย่างแน่นอน - หากคุณมีมากขึ้นสิ่งนี้อาจนำไปสู่แผนการปฏิบัติที่ไม่ดีอย่างจริงจัง