Sì, c'è una differenza di prestazioni piuttosto grande tra:
declare @numbers table (n int not null primary key clustered);
insert into @numbers (n)
values (0)
, (1)
, (2)
, (3)
, (4);
e
declare @numbers table (n int not null primary key clustered);
insert into @numbers (n) values (0);
insert into @numbers (n) values (1);
insert into @numbers (n) values (2);
insert into @numbers (n) values (3);
insert into @numbers (n) values (4);
Il fatto che ogni singolo insert
dichiarazione ha una propria transazione implicita garantisce questo. Puoi dimostrarlo facilmente visualizzando i piani di esecuzione per ciascuna istruzione o cronometrando le esecuzioni utilizzando set statistics time on;
. C'è un costo fisso associato alla "configurazione" e allo "smontaggio" del contesto per ogni singolo inserto e la seconda query deve pagare questa penale cinque volte mentre la prima la paga una sola volta.
Non solo il metodo list è più efficiente, ma puoi anche usarlo per creare una tabella derivata:
select *
from (values
(0)
, (1)
, (2)
, (3)
, (4)
) as Numbers (n);
Questo formato aggira il limite di 1.000 valori e ti consente di unire e filtrare l'elenco prima che venga inserito. Si potrebbe anche notare che non siamo vincolati all'insert
dichiarazione a tutti! In quanto tabella de facto, questo costrutto può essere utilizzato ovunque sia valido un riferimento a una tabella.