logische Lesevorgänge für die globale temporäre Tabelle, jedoch nicht für die temporäre Tabelle auf Sitzungsebene

11

Betrachten Sie das folgende einfache MCVE:

SET STATISTICS IO, TIME OFF;
USE tempdb;

IF OBJECT_ID(N'tempdb..#t1', N'U') IS NOT NULL DROP TABLE #t1;
CREATE TABLE #t1
(
    r int NOT NULL
);

IF OBJECT_ID(N'tempdb..##t1', N'U') IS NOT NULL DROP TABLE ##t1;
CREATE TABLE ##t1
(
    r int NOT NULL
);

IF OBJECT_ID(N'dbo.s1', N'U') IS NOT NULL DROP TABLE dbo.s1;
CREATE TABLE dbo.s1 
(
    r int NOT NULL
        PRIMARY KEY CLUSTERED
);

INSERT INTO dbo.s1 (r)
SELECT TOP(10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM sys.syscolumns sc1
    CROSS JOIN sys.syscolumns sc2;
GO

Wenn ich die folgenden Einfügungen ausführe, werden beim Einfügen in #t1keine Statistik-E / A für die temporäre Tabelle angezeigt. Beim Einfügen in werden ##t1 jedoch Statistik-E / A für die temporäre Tabelle angezeigt.

SET STATISTICS IO, TIME ON;
GO

INSERT INTO #t1 (r)
SELECT r
FROM dbo.s1;

Die Statistikausgabe:

SQL Server-Analyse- und Kompilierungszeit: 
   CPU-Zeit = 0 ms, verstrichene Zeit = 1 ms.
Tabelle 's1'. Scananzahl 1, logische Lesevorgänge 19, physische Lesevorgänge 0, Vorauslesevorgänge 0, Lob-Lesevorgänge 0, Lob-Lesevorgänge 0, Lobvorlesevorgänge 0.

 SQL Server-Ausführungszeiten:
   CPU-Zeit = 16 ms, verstrichene Zeit = 9 ms.

(10000 Zeilen betroffen)
INSERT INTO ##t1 (r)
SELECT r
FROM dbo.s1;
SQL Server-Analyse- und Kompilierungszeit: 
   CPU-Zeit = 0 ms, verstrichene Zeit = 1 ms.
Tabelle '## t1'. Scananzahl 0, logische Lesevorgänge 10016, physische Lesevorgänge 0, Vorauslesevorgänge 0, Lob-Lesevorgänge 0, Lob-Lesevorgänge 0, Lobvorlesevorgänge 0.
Tabelle 's1'. Scananzahl 1, logische Lesevorgänge 19, physische Lesevorgänge 0, Vorauslesevorgänge 0, Lob-Lesevorgänge 0, Lob-Lesevorgänge 0, Lobvorlesevorgänge 0.

 SQL Server-Ausführungszeiten:
   CPU-Zeit = 47 ms, verstrichene Zeit = 45 ms.

(10000 Zeilen betroffen)

Warum gibt es so viele Lesevorgänge in der ## temp-Tabelle, wenn ich sie nur einfüge?

Max Vernon
quelle

Antworten:

11

Bei Verwendung INSERT INTOglobaler 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.

Geben Sie hier die Bildbeschreibung ein

Eine LOP_INSERT_ROWOperation 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)

Geben Sie hier die Bildbeschreibung ein

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;

Geben Sie hier die Bildbeschreibung ein

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 INTOnicht 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.

Randi Vertongen
quelle