ตารางชั่วคราวในพื้นที่และทั่วโลกใน SQL Server


156

ความแตกต่างระหว่างตารางชั่วคราวในพื้นที่และส่วนกลางใน SQL Server คืออะไร?


2
นี่คือรายละเอียดสรุปบางอย่างเกี่ยวกับเรื่องนี้คลิกที่นี่
Jayesh Sorathia

5
ระวังเมื่อใช้ตัวแปรตาราง หากคุณใช้พวกเขาในแบบสอบถามพวกเขาสามารถนำไปสู่ปัญหาประสิทธิภาพการทำงานอย่างรุนแรงกับแผนแบบสอบถามของคุณเพราะพวกเขาไม่ได้จัดทำดัชนี

ที่จริงแล้วตาราง temp นั้นสามารถสร้างดัชนีได้ถ้าต้องการ แต่มันต้องใช้เวลาและทรัพยากรเช่นกันดังนั้นมันยังอาจทำให้เกิดปัญหาด้านประสิทธิภาพหรือทรัพยากร
Andrew Steitz

คำตอบ:


114

ฉันพบว่าคำอธิบายนี้ค่อนข้างชัดเจน (เป็นสำเนาแท้จากTechnet ):

ตารางชั่วคราวมีสองประเภท: ท้องถิ่นและทั่วโลก ตารางชั่วคราวในพื้นที่จะปรากฏเฉพาะกับผู้สร้างของพวกเขาในระหว่างการเชื่อมต่อกับอินสแตนซ์ของ SQL Server เดียวกับเมื่อตารางถูกสร้างหรืออ้างอิงเป็นครั้งแรก ตารางชั่วคราวในเครื่องจะถูกลบหลังจากผู้ใช้ยกเลิกการเชื่อมต่อจากอินสแตนซ์ของ SQL Server ตารางชั่วคราวทั่วโลกสามารถมองเห็นได้โดยผู้ใช้และการเชื่อมต่อใด ๆ หลังจากที่พวกเขาสร้างขึ้นและจะถูกลบเมื่อผู้ใช้ทั้งหมดที่อ้างอิงตารางยกเลิกการเชื่อมต่อจากอินสแตนซ์ของ SQL Server


ยอดเยี่ยมคำตอบที่เป็นประโยชน์! ฉันกำลังมองหาข้อมูลเฉพาะในกรณีที่ / เมื่อตารางชั่วคราวทั่วโลกถูกล้างข้อมูลโดยอัตโนมัติโดย SQL Server
kwill

คำตอบที่ชัดเจนและรัดกุมมาก ทุกคนสามารถนึกถึงกรณีการใช้ที่ดีสำหรับตารางชั่วคราวทั่วโลกได้หรือไม่ หนึ่งที่แสดงให้เห็นถึงจุดประสงค์ของพวกเขาในทางตรงกันข้ามกับวัตถุประสงค์ของตารางอุณหภูมิท้องถิ่น?
เทรเวอร์

336
  • ตัวแปรตาราง ( DECLARE @t TABLE) สามารถมองเห็นได้เฉพาะกับการเชื่อมต่อที่สร้างขึ้นและจะถูกลบเมื่อแบตช์หรือกระบวนงานที่เก็บไว้สิ้นสุดลง

  • ตารางชั่วคราวท้องถิ่น ( CREATE TABLE #t) จะปรากฏต่อการเชื่อมต่อที่สร้างขึ้นเท่านั้นและจะถูกลบเมื่อการเชื่อมต่อถูกปิด

  • ตารางชั่วคราวทั่วโลก ( CREATE TABLE ##t) จะปรากฏแก่ทุกคนและจะถูกลบออกเมื่อการเชื่อมต่อทั้งหมดที่มีการอ้างถึงพวกเขาได้ปิด

  • USE tempdb CREATE TABLE tทุกคนสามารถเห็นตาราง Tempdb ถาวร ( ) และจะถูกลบเมื่อเซิร์ฟเวอร์เริ่มต้นใหม่


55
ค่าที่ควรทราบอีกด้วย: ตารางชั่วคราวในตัวเครื่องจะถูกลบเมื่อขอบเขตที่สร้างขึ้นถูกปิด ดังนั้นถ้าคุณสร้างตารางอุณหภูมิภายใน sproc แล้วลองและเข้าถึงมันนอก sproc นั้น - มันจะไม่มีอยู่

+1 สำหรับความประสงค์ ฉันพยายามใช้ตารางชั่วคราวในพื้นที่เป็นเครื่องมือเพิ่มประสิทธิภาพและฉันพยายามใช้ขั้นตอนการจัดเก็บเป็น "สร้างและเติมหากไม่มีตัวเริ่มต้น" อย่างที่คุณพูดมันไม่ทำงานจนกว่าคุณจะใช้ตารางชั่วคราวทั่วโลกแทน
quillbreaker

9
"จะถูกลบเมื่อการเชื่อมต่อทั้งหมดที่อ้างอิงได้ปิดไปแล้ว" - "ที่อ้างอิงพวกเขา" หมายความว่าอะไร? หาก StoredProc จากการเชื่อมต่อหนึ่ง # 1 สร้าง ## TempTable ฉันสามารถดูได้จากการเชื่อมต่ออื่น # 2 บอกว่า 10 นาทีต่อมา (ถ้าการเชื่อมต่อนั้น # 2 ใช้งานในเวลาที่สร้างตาราง?) คำตอบ: ตารางชั่วคราวทั่วโลก เซสชันที่สร้างตารางสิ้นสุดและงานอื่น ๆ ทั้งหมดได้หยุดการอ้างอิงพวกเขา (ดูรายละเอียดเพิ่มเติมได้ที่หน้านี้ในคำตอบที่แตกต่างกัน)
tbone

ฉันพยายามใช้โพรซีเดอร์ที่เก็บไว้เพื่อสร้างตารางชั่วคราวโลคัล (#t) ที่ต้องการโดยลอจิกที่ตามมาอย่างไรก็ตามปรากฎว่าโพรซีเดอร์ที่จัดเก็บพาเรนต์ต้องสร้างมันขึ้นมาเพื่อให้พวกเขาสามารถใช้งานได้ นี่เป็นสิ่งที่น่าเศร้าเพราะเรามีกระบวนงานที่เก็บไว้จำนวนมากที่ต้องตั้งค่าตารางในลักษณะเดียวกันและเรียกลงใน sprocs ทั่วไป ตาราง temp ทั่วโลกจะทำงานในกรณีนี้ที่เด็กเรียกมีการเข้าถึงตารางที่สร้างโดยพี่น้อง? เรากำลังใช้ SQL Server 2008
Brandon

1
@Brandon คุณพูดถูก นั่นคือฟังก์ชั่นที่ขาดหายไป การสนับสนุนของ TSQL สำหรับการกำหนดขอบเขตของข้อมูลชั่วคราวนั้นค่อนข้างสมบูรณ์ ราวกับว่านักออกแบบภาษาต้องการให้ทุกสิ่งเป็นสากล และแทบจะไม่มีการสนับสนุนสำหรับการปิด คุณสามารถผ่านตัวแปรเคอร์เซอร์ได้ แต่นั่นเป็นอีกหนอนหนึ่งที่สามารถทำได้เพราะการโจมตีแบบต่อเนื่องเป็นวิธีที่ไม่สามารถทำได้
Anthony Faull

12

1. ) ตารางชั่วคราวในพื้นที่มีอยู่เฉพาะในช่วงเวลาของการเชื่อมต่อหรือถ้ากำหนดไว้ในคำสั่งผสมสำหรับช่วงเวลาของคำสั่งผสม

ตาราง temp เฉพาะที่พร้อมใช้งานสำหรับเซสชัน SQL Server หรือการเชื่อมต่อ (หมายถึงผู้ใช้คนเดียว) ที่สร้างตาราง สิ่งเหล่านี้จะถูกลบโดยอัตโนมัติเมื่อเซสชันที่สร้างตารางถูกปิด ชื่อตารางชั่วคราวในพื้นที่จ้องมองด้วยเครื่องหมายแฮชเดียว ("#")

CREATE TABLE #LocalTemp
(
 UserID int,
 Name varchar(50), 
 Address varchar(150)
)
GO
insert into #LocalTemp values ( 1, 'Name','Address');
GO
Select * from #LocalTemp

ขอบเขตของตาราง Local temp มีอยู่ในเซสชันปัจจุบันของผู้ใช้ปัจจุบันหมายถึงหน้าต่างแบบสอบถามปัจจุบัน หากคุณจะปิดหน้าต่างคิวรีปัจจุบันหรือเปิดหน้าต่างคิวรีใหม่และจะลองค้นหาตาราง temp ที่สร้างขึ้นด้านบนมันจะทำให้คุณเกิดข้อผิดพลาด


2. ) ตารางชั่วคราวทั่วโลกยังคงอยู่ในฐานข้อมูลอย่างถาวร แต่มีแถวอยู่ภายในการเชื่อมต่อที่กำหนด เมื่อปิดการเชื่อมต่อข้อมูลในตารางชั่วคราวทั่วโลกจะหายไป อย่างไรก็ตามคำจำกัดความของตารางยังคงอยู่กับฐานข้อมูลสำหรับการเข้าถึงเมื่อเปิดฐานข้อมูลในครั้งถัดไป

ตาราง temp สากลพร้อมใช้งานสำหรับทุกเซสชันของ SQL Server หรือการเชื่อมต่อ (หมายถึงผู้ใช้ทั้งหมด) สิ่งเหล่านี้สามารถสร้างโดยผู้ใช้การเชื่อมต่อ SQL Server และสิ่งเหล่านี้จะถูกลบโดยอัตโนมัติเมื่อการเชื่อมต่อ SQL Server ทั้งหมดถูกปิด ชื่อตารางชั่วคราวส่วนกลางถูกจ้องด้วยเครื่องหมายแฮชคู่ ("##")

CREATE TABLE ##GlobalTemp
(
 UserID int,
 Name varchar(50), 
 Address varchar(150)
)
GO
insert into ##GlobalTemp values ( 1, 'Name','Address');
GO
Select * from ##GlobalTemp

ตารางชั่วคราวทั่วโลกสามารถมองเห็นได้ในการเชื่อมต่อ SQL Server ทั้งหมดในขณะที่ตารางชั่วคราวภายในสามารถมองเห็นได้เฉพาะการเชื่อมต่อ SQL Server ปัจจุบันเท่านั้น


2
คำจำกัดความของคุณของตารางชั่วคราวทั่วโลกคือวิธีที่ฉันคาดหวังให้ปฏิบัติ (มาจากฐานข้อมูลอื่น) แต่การทดสอบของฉันแสดงให้เห็นว่าสิ่งที่เกิดขึ้นจริงใน SQL Server คือ: "ตารางชั่วคราวทั่วโลกจะถูกลบโดยอัตโนมัติเมื่อเซสชันที่สร้างตาราง สิ้นสุดลงและงานอื่น ๆ ทั้งหมดได้หยุดการอ้างอิงพวกเขา "
โคล 7

11

การอ้างอิงจากหนังสือออนไลน์:

ตารางชั่วคราวในพื้นที่จะปรากฏเฉพาะในเซสชันปัจจุบันเท่านั้น ตารางชั่วคราวทั่วโลกสามารถมองเห็นได้ในทุกเซสชัน

ตารางชั่วคราวจะถูกดร็อปโดยอัตโนมัติเมื่อไม่อยู่ในขอบเขตยกเว้นว่าดร็อปอย่างชัดเจนโดยใช้ DROP TABLE:

  • ตารางชั่วคราวในตัวเครื่องที่สร้างขึ้นในขั้นตอนการจัดเก็บจะลดลงโดยอัตโนมัติเมื่อขั้นตอนการจัดเก็บเสร็จสมบูรณ์ ตารางสามารถอ้างอิงโดยโพรซีเดอร์ที่จัดเก็บแบบซ้อนใด ๆ ที่ดำเนินการโดยโพรซีเดอร์ที่เก็บที่สร้างตาราง ไม่สามารถอ้างอิงตารางโดยกระบวนการที่เรียกว่ากระบวนงานที่เก็บไว้ซึ่งสร้างตาราง
  • ตารางชั่วคราวท้องถิ่นอื่น ๆ ทั้งหมดจะถูกดร็อปโดยอัตโนมัติเมื่อสิ้นสุดเซสชันปัจจุบัน
  • ตารางชั่วคราวทั่วโลกจะถูกดร็อปโดยอัตโนมัติเมื่อเซสชันที่สร้างตารางสิ้นสุดและงานอื่น ๆ ทั้งหมดหยุดการอ้างอิง ความสัมพันธ์ระหว่างงานและตารางได้รับการดูแลรักษาไว้ตลอดชีวิตของคำสั่ง Transact-SQL เดียว ซึ่งหมายความว่าตารางชั่วคราวทั่วโลกจะถูกดร็อปเมื่อเสร็จสิ้นคำสั่ง Transact-SQL ล่าสุดซึ่งอ้างอิงตารางอย่างแข็งขันเมื่อการสร้างเซสชันสิ้นสุดลง

0

ตารางชั่วคราวในเครื่อง : หากคุณสร้างตารางชั่วคราวในเครื่องจากนั้นเปิดการเชื่อมต่ออื่นแล้วลองสอบถามคุณจะได้รับข้อผิดพลาดดังต่อไปนี้

ตารางชั่วคราวสามารถเข้าถึงได้ภายในเซสชันที่สร้างขึ้นเท่านั้น

ตารางชั่วคราวทั่วโลก : บางครั้งคุณอาจต้องการสร้างตารางชั่วคราวที่สามารถเข้าถึงการเชื่อมต่ออื่น ๆ ในกรณีนี้คุณสามารถใช้ตารางชั่วคราวทั่วโลก

ตารางชั่วคราวทั่วโลกจะถูกทำลายเมื่อทุกเซสชันที่อ้างถึงถูกปิด


0

เป็นมูลค่าการกล่าวขวัญว่ายังมี: ฐานข้อมูลตารางชั่วคราวทั่วโลกกำหนดขอบเขต (ปัจจุบันสนับสนุนโดยฐานข้อมูล Azure SQL เท่านั้น)

ตารางชั่วคราวทั่วโลกสำหรับ SQL Server (เริ่มต้นด้วย ## ชื่อตาราง) จะถูกเก็บไว้ใน tempdb และใช้ร่วมกันระหว่างเซสชันของผู้ใช้ทั้งหมดในอินสแตนซ์ของ SQL Server ทั้งหมด

Azure SQL Database สนับสนุนตารางชั่วคราวส่วนกลางที่เก็บไว้ใน tempdb และกำหนดขอบเขตให้อยู่ในระดับฐานข้อมูล ซึ่งหมายความว่าตารางชั่วคราวทั่วโลกจะถูกใช้ร่วมกันสำหรับเซสชันของผู้ใช้ทั้งหมดภายในฐานข้อมูล Azure SQL เดียวกัน เซสชันผู้ใช้จากฐานข้อมูลอื่นไม่สามารถเข้าถึงตารางชั่วคราวทั่วโลก

-- Session A creates a global temp table ##test in Azure SQL Database testdb1
-- and adds 1 row
CREATE TABLE ##test ( a int, b int);
INSERT INTO ##test values (1,1);

-- Session B connects to Azure SQL Database testdb1 
-- and can access table ##test created by session A
SELECT * FROM ##test
---Results
1,1

-- Session C connects to another database in Azure SQL Database testdb2 
-- and wants to access ##test created in testdb1.
-- This select fails due to the database scope for the global temp tables 
SELECT * FROM ##test
---Results
Msg 208, Level 16, State 0, Line 1
Invalid object name '##test'

เปลี่ยนฐานข้อมูลกำหนดค่าขอบเขตแล้ว

GLOBAL_TEMPORARY_TABLE_AUTODROP = { ON | OFF }

นำไปใช้กับ: ฐานข้อมูล Azure SQL (คุณลักษณะอยู่ในหน้าตัวอย่างสาธารณะ)

อนุญาตให้ตั้งค่าฟังก์ชั่นการปล่อยอัตโนมัติสำหรับตารางชั่วคราวทั่วโลก ค่าเริ่มต้นคือ ON ซึ่งหมายความว่าตารางชั่วคราวทั่วโลกจะถูกลบโดยอัตโนมัติเมื่อไม่ได้ใช้งานโดยเซสชันใด ๆ เมื่อตั้งค่าเป็นปิดตารางชั่วคราวทั่วโลกจะต้องลดลงอย่างชัดเจนโดยใช้คำสั่ง DROP TABLE หรือจะลดลงโดยอัตโนมัติเมื่อเซิร์ฟเวอร์รีสตาร์ท

ด้วยฐานข้อมูลเดียวของ Azure SQL และพูลที่ยืดหยุ่นตัวเลือกนี้สามารถตั้งค่าในฐานข้อมูลผู้ใช้แต่ละรายของเซิร์ฟเวอร์ฐานข้อมูล SQL ในอินสแตนซ์ที่ได้รับการจัดการของ SQL Server และ Azure SQL Database ตัวเลือกนี้จะถูกตั้งค่าใน TempDB และการตั้งค่าของฐานข้อมูลผู้ใช้แต่ละรายจะไม่มีผลใด ๆ


0

ฉันไม่เห็นคำตอบใด ๆ แสดงให้ผู้ใช้เห็นว่าเราสามารถหาตารางอุณหภูมิชั่วคราวได้หรือไม่ คุณสามารถดูตารางชั่วคราวและทั่วโลกในสถานที่เดียวกันเมื่อนำทางภายใน SSMS ภาพหน้าจอด้านล่างนำมาจากลิงก์นี้

ฐานข้อมูล -> ฐานข้อมูลระบบ -> tempdb -> ตารางชั่วคราว

ป้อนคำอธิบายรูปภาพที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.