Na verdade, do jeito que você escreveu, sua primeira opção será mais rápida.
-
Seu segundo exemplo tem um problema nele. Você está fazendo sql =+ sql + etc. Isso fará com que um novo objeto string seja criado para cada iteração do loop. (Confira a classe StringBuilder). Tecnicamente, você também criará um novo objeto de string em primeira instância, mas a diferença é que ele não precisa copiar todas as informações da opção de string anterior.
-
Da maneira como você o configurou, o SQL Server terá que avaliar potencialmente uma consulta enorme quando você finalmente a enviar, o que definitivamente levará algum tempo para descobrir o que deve fazer. Devo afirmar que isso depende de quão grande é o número de inserções que você precisa fazer. Se n for pequeno, você provavelmente ficará bem, mas à medida que cresce, seu problema só vai piorar.
As inserções em massa são mais rápidas do que as individuais devido à forma como o SQL Server lida com as transações em lote. Se você for inserir dados de C#, você deve usar a primeira abordagem e envolver, digamos, cada 500 inserções em uma transação e confirmá-la, depois fazer as próximas 500 e assim por diante. Isso também tem a vantagem de que, se um lote falhar, você pode interceptá-los e descobrir o que deu errado e reinserir apenas esses. Existem outras maneiras de fazer isso, mas isso definitivamente seria uma melhoria em relação aos dois exemplos fornecidos.
var iCounter = 0;
foreach (Employee item in employees)
{
if (iCounter == 0)
{
cmd.BeginTransaction;
}
string sql = @"INSERT INTO Mytable (id, name, salary)
values ('@id', '@name', '@salary')";
// replace @par with values
cmd.CommandText = sql; // cmd is IDbCommand
cmd.ExecuteNonQuery();
iCounter ++;
if(iCounter >= 500)
{
cmd.CommitTransaction;
iCounter = 0;
}
}
if(iCounter > 0)
cmd.CommitTransaction;