Những câu trả lời cho câu hỏi này cho đến nay đã được rất sai lầm (và chứng minh sự thiếu hoàn chỉnh các nỗ lực/sự hiểu biết) là có một sự khác biệt hiệu suất khá lớn giữa:
declare @numbers table (n int not null primary key clustered);
insert into @numbers (n)
values (0)
, (1)
, (2)
, (3)
, (4);
và
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);
Thực tế là mỗi câu lệnh insert
đơn lẻ đều có giao dịch ngầm riêng đảm bảo điều này. Bạn có thể tự mình chứng minh điều này bằng cách xem các kế hoạch thực hiện cho từng câu lệnh hoặc theo thời gian thực hiện bằng cách sử dụng set statistics time on;
. Có một chi phí cố định liên quan đến "thiết lập" và "xé xuống" ngữ cảnh cho mỗi lần chèn riêng lẻ và truy vấn thứ hai phải trả tiền phạt này năm lần trong khi lần đầu tiên chỉ trả tiền một lần.
Không chỉ là phương pháp danh sách hiệu quả hơn nhưng bạn cũng có thể sử dụng nó để xây dựng một bảng có nguồn gốc:
select *
from (values
(0)
, (1)
, (2)
, (3)
, (4)
) as Numbers (n);
Định dạng này được xung quanh giới hạn 1.000 giá trị và cho phép bạn tham gia và lọc danh sách của bạn trước khi nó được chèn vào. Người ta cũng có thể nhận thấy rằng chúng tôi không bị ràng buộc với tuyên bố insert
! Là một bảng thực tế, cấu trúc này có thể được sử dụng ở bất kỳ nơi nào một tham chiếu bảng sẽ hợp lệ.
Thực ra, có thể có lợi ích hiệu suất đáng kể nếu một số lượng lớn các câu lệnh INSERT riêng lẻ sẽ được gửi qua kết nối mạng. Xem [câu trả lời của tôi ở đây] (http://stackoverflow.com/a/25879264/2144390) để biết ví dụ. –