[SQL 2008] Insert & Minimal Logging
Un nuovo comportamento, ancora poco pubblicizzato, ma a mio parere molto interessante, riguarda la possibilità di utilizzare una INSERT INTO ... SELECT ... con un logging minimo, così come posso avere utilizzando strumenti di caricamento massivo come la BULK INSERT o il comando BCP.
Un esempio rapido... Scenario: voglio inserire in una nuova (vuota) tabella 100.000 righe provenienti da un'altra tabella.
Ovvero: insert into copydata select a, b from data;
Utilizzo SQL Server 2005 e SQL Server 2008 per vedere le differenze di comportamento.
Alcune note:
- il database deve essere in recovery model SIMPLE
- devo utilizzare l'hint di tabella TABLOCK sulla tabella di destinazione
- non posso avere indici clustered sulla tabella di destinazione
Per conoscere il numero di righe loggate nel Transaction Log utilizzeremo la funzione *non documentata* fn_dblog, semplicemente facendo un SELECT COUNT(*) ...
Questo il codice:
create table copydata(a int not null, b char(200) not null);
go
checkpoint;
go
select COUNT(*) n from ::fn_dblog(null, null);
insert into copydata with(tablock)
select a, b from data;
select COUNT(*) n from ::fn_dblog(null, null);
go
I risultati:
- SQL 2005
- numero di log records 120.015
- tempo di esecuzione: 15 secondi
- SQL 2008
- numero di log records 4.801
- tempo di esecuzione: 5 secondi

Non male, no?