La registrazione minima non viene utilizzata durante l'utilizzo INSERT INTO
e le tabelle temporanee globali
Inserendo un milione di righe in una tabella temporanea globale usando INSERT INTO
INSERT INTO ##t1 (r)
SELECT top(1000000) s1.r
FROM dbo.s1
CROSS APPLY dbo.s1 S2;
Durante l'esecuzione SELECT * FROM fn_dblog(NULL, NULL)
mentre la query sopra è in esecuzione, vengono restituite ~ 1 milione di righe.
LOP_INSERT_ROW
Un'operazione per ogni altri dati di log fila +.
Lo stesso inserto su una tabella temporanea locale
INSERT INTO #t1 (r)
SELECT top(1000000) s1.r
FROM dbo.s1
CROSS APPLY dbo.s1 S2;
Restituito solo da un massimo di 700 righe SELECT * FROM fn_dblog(NULL, NULL)
Registrazione minima
Inserendo un milione di righe in una tabella temporanea globale usando SELECT INTO
SELECT top(1000000) s1.r
INTO ##t2
FROM dbo.s1
CROSS APPLY dbo.s1 S2;
SELECT INTO
una tabella temporanea globale con record 10k
SELECT s1.r
INTO ##t2
FROM dbo.s1;
Time and IO Statistics
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.
Sulla base di questo post di blog possiamo aggiungere TABLOCK
per avviare la registrazione minima su una tabella heap
INSERT INTO ##t1 WITH(TABLOCK) (r)
SELECT s1.r
FROM dbo.s1
Letture logiche basse
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)
Parte di una risposta di @PaulWhite su come ottenere una registrazione minima su tabelle temporanee
No. Le tabelle temporanee locali (#temp) sono private per la sessione di creazione, quindi non è richiesto un suggerimento per il blocco delle tabelle. Un suggerimento per il blocco delle tabelle sarebbe necessario per una tabella temporanea globale (## temp) o una tabella normale (dbo.temp) creata in tempdb, poiché è possibile accedervi da più sessioni.
Creazione di una tabella regolare per testare questo:
CREATE TABLE dbo.bla
(
r int NOT NULL
);
Riempiendo con record 1M
INSERT INTO bla
SELECT top(1000000)s1.r
FROM dbo.s1
CROSS APPLY dbo.s1 S2;
> 1M letture logiche su questa tabella
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.
La risposta di Paul White che spiega le letture logiche riportate nella tabella delle temp globali
In genere, le letture logiche vengono riportate per la tabella di destinazione quando l'inserimento non è minimamente registrato.
Queste letture logiche sono associate alla ricerca di un posto nella struttura esistente per aggiungere le nuove righe. Gli inserti con registrazione minima utilizzano il meccanismo di caricamento di massa, che alloca pagine / estensioni completamente nuove (e quindi non è necessario leggere la struttura di destinazione allo stesso modo).
Conclusione
La conclusione è che INSERT INTO
non è in grado di utilizzare la registrazione minima, risultando nella registrazione di ogni riga inserita singolarmente nel file di registro di tempdb quando utilizzata in combinazione con una tabella temporanea globale / tabella normale. Considerando che la tabella temporanea locale / SELECT INTO
/ INSERT INTO ... WITH(TABLOCK)
è in grado di utilizzare la registrazione minima.