Ответы на этот вопрос до сих пор были чрезвычайно вводящими в заблуждение (и демонстрировали полное отсутствие усилий / понимания), так как существует довольно большая разница в производительности между:
declare @numbers table (n int not null primary key clustered);
insert into @numbers (n)
values (0)
, (1)
, (2)
, (3)
, (4);
и
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);
Тот факт, что каждый оператор insert
имеет свою собственную неявную транзакцию, гарантирует это. Вы можете легко доказать это, просмотрев планы выполнения для каждого оператора или выбрав время выполнения, используя set statistics time on;
. Существует фиксированная стоимость, связанная с «установкой» и «разрывом» контекста для каждой отдельной вставки, и второй запрос должен платить это штраф пять раз, тогда как первый платит только один раз.
Мало того, что метод list более эффективен, но вы также можете использовать его для построения производной таблицы:
select *
from (values
(0)
, (1)
, (2)
, (3)
, (4)
) as Numbers (n);
Этот формат преодолевает ограничение в 1000 значений и позволяет вам присоединиться и отфильтровать свой список до его вставки. Можно также заметить, что мы вообще не связаны с оператором insert
! Как таблица де-факто, эта конструкция может использоваться везде, где ссылка на таблицу будет действительной.