Bei Verwendung INSERT INTO
globaler temporärer Tabellen wird keine minimale Protokollierung verwendet
Einfügen einer Million Zeilen in eine globale temporäre Tabelle mithilfe von INSERT INTO
INSERT INTO ##t1 (r)
SELECT top(1000000) s1.r
FROM dbo.s1
CROSS APPLY dbo.s1 S2;
Wenn SELECT * FROM fn_dblog(NULL, NULL)
die obige Abfrage ausgeführt wird, werden ~ 1 Million Zeilen zurückgegeben.
Eine LOP_INSERT_ROW
Operation für jede Zeile + andere Protokolldaten.
Dieselbe Einfügung in eine lokale temporäre Tabelle
INSERT INTO #t1 (r)
SELECT top(1000000) s1.r
FROM dbo.s1
CROSS APPLY dbo.s1 S2;
Nur bis zu 700 Zeilen werden von zurückgegeben SELECT * FROM fn_dblog(NULL, NULL)
Minimale Protokollierung
Einfügen einer Million Zeilen in eine globale temporäre Tabelle mithilfe von SELECT INTO
SELECT top(1000000) s1.r
INTO ##t2
FROM dbo.s1
CROSS APPLY dbo.s1 S2;
SELECT INTO
Eine globale temporäre Tabelle mit 10.000 Datensätzen
SELECT s1.r
INTO ##t2
FROM dbo.s1;
Zeit- und E / A-Statistiken
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 16 ms, elapsed time = 10 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
Basierend auf diesem Blogpost können wir hinzufügen TABLOCK
, um eine minimale Protokollierung für eine Heap-Tabelle zu initiieren
INSERT INTO ##t1 WITH(TABLOCK) (r)
SELECT s1.r
FROM dbo.s1
Niedrige logische Lesevorgänge
Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(10000 rows affected)
Teil einer Antwort von @PaulWhite, wie eine minimale Protokollierung für temporäre Tabellen erreicht werden kann
Nein. Lokale temporäre Tabellen (#temp) sind für die Erstellungssitzung privat, sodass kein Tabellensperrhinweis erforderlich ist. Für eine globale temporäre Tabelle (## temp) oder eine reguläre Tabelle (dbo.temp), die in tempdb erstellt wurde, wäre ein Tabellensperrhinweis erforderlich, da auf diese von mehreren Sitzungen aus zugegriffen werden kann.
Erstellen einer regulären Tabelle, um dies zu testen:
CREATE TABLE dbo.bla
(
r int NOT NULL
);
Füllen Sie es mit 1M Datensätzen
INSERT INTO bla
SELECT top(1000000)s1.r
FROM dbo.s1
CROSS APPLY dbo.s1 S2;
> 1M logische Lesevorgänge für diese Tabelle
Table 's1'. Scan count 17, logical reads 155, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'bla'. Scan count 0, logical reads 1001607, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Die Antwort von Paul White erklärt die logischen Lesevorgänge, die in der globalen temporären Tabelle angegeben sind
Im Allgemeinen werden logische Lesevorgänge für die Zieltabelle gemeldet, wenn die Einfügung nicht minimal protokolliert wird.
Diese logischen Lesevorgänge sind mit dem Suchen eines Platzes in der vorhandenen Struktur verbunden, um die neuen Zeilen hinzuzufügen. Minimal protokollierte Einfügungen verwenden den Massenlademechanismus, der ganz neue Seiten / Bereiche zuweist (und daher die Zielstruktur nicht auf die gleiche Weise lesen muss).
Fazit
Die Schlussfolgerung ist, dass das INSERT INTO
nicht in der Lage ist, eine minimale Protokollierung zu verwenden, was dazu führt, dass jede eingefügte Zeile einzeln in der Protokolldatei von tempdb protokolliert wird, wenn sie in Kombination mit einer globalen temporären Tabelle / normalen Tabelle verwendet wird. Während die lokale temporäre Tabelle // SELECT INTO
/ INSERT INTO ... WITH(TABLOCK)
nur minimale Protokollierung verwenden kann.