Lokale und globale temporäre Tabellen in SQL Server

156

Was ist der Unterschied zwischen lokalen und globalen temporären Tabellen in SQL Server?

Andrew Sullivan
quelle
2
Hier sind einige Zusammenfassungen Details dazu, Klicken Sie hier
Jayesh Sorathia
5
Seien Sie vorsichtig, wenn Sie Tabellenvariablen verwenden. Wenn Sie sie in einer Abfrage verwenden, können sie zu schwerwiegenden Leistungsproblemen mit Ihrem Abfrageplan führen, da sie nicht indiziert sind.
Tatsächlich können temporäre Tabellen bei Bedarf indiziert werden, dies erfordert jedoch auch Zeit und Ressourcen, sodass dennoch Leistungs- oder Ressourcenprobleme auftreten können.
Andrew Steitz

Antworten:

114

Ich finde diese Erklärung ziemlich klar (es ist eine reine Kopie von Technet ):

Es gibt zwei Arten von temporären Tabellen: lokale und globale. Lokale temporäre Tabellen sind nur für ihre Ersteller während derselben Verbindung zu einer Instanz von SQL Server sichtbar, als die Tabellen zum ersten Mal erstellt oder referenziert wurden. Lokale temporäre Tabellen werden gelöscht, nachdem der Benutzer die Verbindung zur Instanz von SQL Server getrennt hat. Globale temporäre Tabellen sind für jeden Benutzer und jede Verbindung nach ihrer Erstellung sichtbar und werden gelöscht, wenn alle Benutzer, die auf die Tabelle verweisen, die Verbindung zur Instanz von SQL Server trennen.

Don
quelle
Tolle, hilfreiche Antwort! Ich suchte nach spezifischen Informationen darüber, ob / wann globale temporäre Tabellen von SQL Server automatisch bereinigt wurden.
kwill
Sehr klare und prägnante Antwort. Kann sich jemand einen guten Anwendungsfall für globale temporäre Tabellen vorstellen? Eine, die ihren Zweck im Gegensatz zum Zweck lokaler temporärer Tabellen veranschaulicht?
Trevor
335
  • Tabellenvariablen ( DECLARE @t TABLE) sind nur für die Verbindung sichtbar, die sie erstellt, und werden gelöscht, wenn der Stapel oder die gespeicherte Prozedur endet.

  • Lokale temporäre Tabellen ( CREATE TABLE #t) sind nur für die Verbindung sichtbar, die sie erstellt, und werden gelöscht, wenn die Verbindung geschlossen wird.

  • Globale temporäre Tabellen ( CREATE TABLE ##t) sind für alle sichtbar und werden gelöscht, wenn alle Verbindungen, auf die verwiesen wurde, geschlossen wurden.

  • Temporäre Tempdb-Tabellen ( USE tempdb CREATE TABLE t) sind für alle sichtbar und werden beim Neustart des Servers gelöscht.

Anthony Faull
quelle
55
Hervorzuheben ist auch: Lokale temporäre Tabellen werden gelöscht, wenn der Bereich, in dem sie erstellt wurden, geschlossen wird. Wenn Sie also eine lokale temporäre Tabelle innerhalb eines Sproc erstellen und dann versuchen, außerhalb dieses Sproc darauf zuzugreifen, ist sie nicht vorhanden.
+1 für Will. Ich habe versucht, eine lokale temporäre Tabelle als Optimierer zu verwenden, und ich habe versucht, eine gespeicherte Prozedur als Initialisierer "Erstellen und Auffüllen, wenn sie nicht vorhanden ist" zu verwenden. Wie Sie sagen, funktioniert es nur, wenn Sie stattdessen eine globale temporäre Tabelle verwenden.
Federbrecher
9
"werden gelöscht, wenn alle Verbindungen, die auf sie verwiesen haben, geschlossen wurden" - was bedeutet "die auf sie verwiesen haben" genau? Wenn ein StoredProc von einer Verbindung Nr. 1 eine ## TempTable erstellt, kann ich sie von einer anderen Verbindung Nr. 2 aus etwa 10 Minuten später sehen (wenn diese Verbindung Nr. 2 zum Zeitpunkt der Tabellenerstellung aktiv war?). ANTWORT: Globale temporäre Tabellen werden automatisch gelöscht, wenn die Die Sitzung, in der die Tabelle erstellt wurde, endet und alle anderen Aufgaben verweisen nicht mehr auf sie. (mehr auf dieser Seite in anderer Antwort)
tbone
Ich habe versucht, mit einer gespeicherten Prozedur lokale temporäre Tabellen (#t) zu erstellen, die von der nachfolgenden Logik benötigt werden. Es stellte sich jedoch heraus, dass die übergeordnete gespeicherte Prozedur sie erstellen musste, damit sie für die Aufrufe der untergeordneten gespeicherten Prozedur verfügbar waren. Dies war eine traurige Sache, da wir eine Reihe von gespeicherten Prozeduren haben, die die Tabellen auf die gleiche Weise einrichten und in gemeinsame Sprocs aufrufen müssen. Funktionieren globale temporäre Tabellen in diesem Fall, wenn die untergeordneten Aufrufe Zugriff auf Tabellen haben, die von einem Geschwister erstellt wurden? Wir verwenden SQL Server 2008.
Brandon
1
@Brandon Du hast ganz recht. Dem fehlt die Funktionalität. Die Unterstützung von TSQL für das ordnungsgemäße Scoping transienter Daten ist recht lückenhaft. Es ist, als wollten die Sprachdesigner, dass alles global ist. Und es gibt fast keine Unterstützung für Schließungen. Sie könnten eine Cursor-Variable übergeben. Aber das ist eine andere Dose Würmer, denn Reihe für Reihe ist es kein Weg mehr.
Anthony Faull
12

1.) Eine lokale temporäre Tabelle existiert nur für die Dauer einer Verbindung oder, falls in einer zusammengesetzten Anweisung definiert, für die Dauer der zusammengesetzten Anweisung.

Lokale temporäre Tabellen sind nur für die SQL Server-Sitzung oder -Verbindung (dh Einzelbenutzer) verfügbar, die die Tabellen erstellt hat. Diese werden automatisch gelöscht, wenn die Sitzung, in der die Tabellen erstellt wurden, geschlossen wurde. Der Name der lokalen temporären Tabelle wird mit einem einzelnen Hash-Zeichen ("#") angezeigt.

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

Der Bereich der lokalen temporären Tabelle existiert für die aktuelle Sitzung des aktuellen Benutzers bedeutet für das aktuelle Abfragefenster. Wenn Sie das aktuelle Abfragefenster schließen oder ein neues Abfragefenster öffnen und versuchen, die oben erstellte temporäre Tabelle zu finden, wird der Fehler angezeigt.


2.) Eine globale temporäre Tabelle bleibt dauerhaft in der Datenbank, aber die Zeilen existieren nur innerhalb einer bestimmten Verbindung. Wenn die Verbindung geschlossen wird, verschwinden die Daten in der globalen temporären Tabelle. Die Tabellendefinition verbleibt jedoch beim Zugriff auf die Datenbank, wenn die Datenbank das nächste Mal geöffnet wird.

Globale temporäre Tabellen stehen allen SQL Server-Sitzungen oder -Verbindungen zur Verfügung (dh allen Benutzern). Diese können von jedem SQL Server-Verbindungsbenutzer erstellt werden und werden automatisch gelöscht, wenn alle SQL Server-Verbindungen geschlossen wurden. Der Name der globalen temporären Tabelle wird mit einem doppelten Hash-Zeichen ("##") angezeigt.

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

Globale temporäre Tabellen sind für alle SQL Server-Verbindungen sichtbar, während lokale temporäre Tabellen nur für die aktuelle SQL Server-Verbindung sichtbar sind.

Vivek S.
quelle
2
Ihre Definition einer globalen temporären Tabelle ist so, wie ich es erwarten würde (von anderen DBs), aber meine Tests zeigen, dass in SQL Server tatsächlich Folgendes passiert: "Globale temporäre Tabellen werden automatisch gelöscht, wenn die Sitzung die Tabelle erstellt endet und alle anderen Aufgaben haben aufgehört, sie zu referenzieren "
Nickolay
11

Zitat aus Books Online:

Lokale temporäre Tabellen sind nur in der aktuellen Sitzung sichtbar. Globale temporäre Tabellen sind für alle Sitzungen sichtbar.

Temporäre Tabellen werden automatisch gelöscht, wenn sie den Gültigkeitsbereich verlassen, es sei denn, sie werden explizit mit DROP TABLE gelöscht:

  • Eine lokale temporäre Tabelle, die in einer gespeicherten Prozedur erstellt wurde, wird automatisch gelöscht, wenn die gespeicherte Prozedur abgeschlossen ist. Auf die Tabelle kann von allen verschachtelten gespeicherten Prozeduren verwiesen werden, die von der gespeicherten Prozedur ausgeführt werden, die die Tabelle erstellt hat. Die Tabelle kann nicht von dem Prozess referenziert werden, der die gespeicherte Prozedur aufgerufen hat, mit der die Tabelle erstellt wurde.
  • Alle anderen lokalen temporären Tabellen werden am Ende der aktuellen Sitzung automatisch gelöscht.
  • Globale temporäre Tabellen werden automatisch gelöscht, wenn die Sitzung, in der die Tabelle erstellt wurde, endet und alle anderen Aufgaben nicht mehr auf sie verweisen. Die Zuordnung zwischen einer Aufgabe und einer Tabelle wird nur für die Lebensdauer einer einzelnen Transact-SQL-Anweisung beibehalten. Dies bedeutet, dass eine globale temporäre Tabelle nach Abschluss der letzten Transact-SQL-Anweisung gelöscht wird, die beim Beenden der Erstellungssitzung aktiv auf die Tabelle verwiesen hat.
Christian Hayter
quelle
0

Lokale temporäre Tabellen : Wenn Sie lokale temporäre Tabellen erstellen und dann eine andere Verbindung öffnen und die Abfrage versuchen, wird der folgende Fehler angezeigt.

Auf die temporären Tabellen kann nur innerhalb der Sitzung zugegriffen werden, in der sie erstellt wurden.

Globale temporäre Tabellen : Manchmal möchten Sie möglicherweise eine temporäre Tabelle erstellen, auf die andere Verbindungen zugreifen können. In diesem Fall können Sie globale temporäre Tabellen verwenden.

Globale temporäre Tabellen werden nur zerstört, wenn alle darauf verweisenden Sitzungen geschlossen sind.

Reza Jenabi
quelle
0

Es ist erwähnenswert, dass es auch Folgendes gibt: globale temporäre Tabellen mit Datenbankbereich (derzeit nur von Azure SQL Database unterstützt).

Globale temporäre Tabellen für SQL Server (initiiert mit dem Tabellennamen ##) werden in Tempdb gespeichert und von allen Benutzersitzungen in der gesamten SQL Server-Instanz gemeinsam genutzt.

Die Azure SQL-Datenbank unterstützt globale temporäre Tabellen, die ebenfalls in Tempdb gespeichert sind und sich auf die Datenbankebene erstrecken. Dies bedeutet, dass globale temporäre Tabellen für alle Benutzersitzungen in derselben Azure SQL-Datenbank freigegeben werden. Benutzersitzungen aus anderen Datenbanken können nicht auf globale temporäre Tabellen zugreifen.

-- 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'

ALTER DATABASE SCOPED CONFIGURATION

GLOBAL_TEMPORARY_TABLE_AUTODROP = { ON | OFF }

GILT FÜR: Azure SQL-Datenbank (Funktion in der öffentlichen Vorschau)

Ermöglicht das Festlegen der Auto-Drop-Funktion für globale temporäre Tabellen. Der Standardwert ist ON. Dies bedeutet, dass die globalen temporären Tabellen automatisch gelöscht werden, wenn sie von keiner Sitzung verwendet werden. Wenn diese Option auf OFF gesetzt ist, müssen globale temporäre Tabellen explizit mit einer DROP TABLE-Anweisung gelöscht werden oder werden beim Neustart des Servers automatisch gelöscht.

Bei einzelnen Azure SQL-Datenbankdatenbanken und elastischen Pools kann diese Option in den einzelnen Benutzerdatenbanken des SQL-Datenbankservers festgelegt werden. In der verwalteten Instanz von SQL Server und Azure SQL Database ist diese Option in TempDB festgelegt, und die Einstellung der einzelnen Benutzerdatenbanken hat keine Auswirkungen.

Lukasz Szozda
quelle
0

Ich habe keine Antworten gesehen, die Benutzern zeigen, wo wir eine Global Temp-Tabelle finden können. Sie können lokale und globale temporäre Tabellen an derselben Stelle anzeigen, wenn Sie in SSMS navigieren. Screenshot unten von diesem Link .

Datenbanken -> Systemdatenbanken -> Tempdb -> Temporäre Tabellen

Geben Sie hier die Bildbeschreibung ein

Code Anfänger
quelle