Команда вставки C # SQL - PullRequest
       29

Команда вставки C # SQL

4 голосов
/ 22 ноября 2011

Может кто-нибудь сказать мне следующие 2 способа вставки записи создает лучшую производительность?

Дело 1

SqlCommand cmd = new SqlCommand();

for (int i = 0; i < 10000; i++)
{
  cmd = new SqlCommand("insert into test(id, name) value('" + i + "', '" + i + "')");
  cmd.ExecuteNonQuery();
}

Дело 2

string sql = null;

for (int i = 0; i < 10000; i++)
{
  sql += "insert into test(id, name) value('" + i + "', '" + i + "')";
}

SqlCommand cmd = new SqlCommand(sql, conn);
cmd.ExecuteNonQuery();

Ответы [ 5 ]

59 голосов
/ 22 ноября 2011

Прежде всего: STOP объединение вашего кода SQL !! Это приглашение хакерам везде, чтобы атаковать вас с помощью SQL-инъекции! Вместо этого используйте параметризованные запросы !

Я бы использовал это решение: создайте single SqlCommand с параметризованным запросом и выполните это:

string stmt = "INSERT INTO dbo.Test(id, name) VALUES(@ID, @Name)";

SqlCommand cmd = new SqlCommand(smt, _connection);
cmd.Parameters.Add("@ID", SqlDbType.Int);
cmd.Parameters.Add("@Name", SqlDbType.VarChar, 100);

for (int i = 0; i < 10000; i++)
{
    cmd.Parameters["@ID"].Value = i;
    cmd.Parameters["@Name"].Value = i.ToString();

    cmd.ExecuteNonQuery();
}

или используйте SqlBulkCopy, особенно если вы вставляете даже более 10 000 строк.

6 голосов
/ 22 ноября 2011

Второй подход выглядит быстрее, чем # 1, потому что вы отправляете команды INSERT сразу. В первом случае для каждого ExecuteNonQuery есть обратный путь к серверу SQL.

Но вы должны попробовать команду массовой вставки: BULK INSERT (Transact-SQL) , я полагаю, вы получите лучшую производительность, чем любая из предложенных вами опций.

[] s

1 голос
/ 22 ноября 2011

Следует отметить, что как есть, ни один из случаев не будет работать.

Случай № 1 требует указания соединения.

Случай № 2 требует, чтобы вы заканчивали свои операторы точкой с запятой, чтобы выполнить несколько команд, например так:

string sql = null;

for (int i = 0; i < 10000; i++)
{
  sql += "insert into test(id, name) value('" + i + "', '" + i + "');";
}

SqlCommand cmd = new SqlCommand(sql, conn);
cmd.ExecuteNonQuery();

В конечном итоге лучшим способом было бы проверить себя на нескольких тысячах строк. Мое предположение состоит в том, что вариант № 2 будет лучше для производительности, потому что он не только потребует установки только одного SqlCommand объекта, но и только ударит базу данных один раз.

1 голос
/ 22 ноября 2011

Не думаю, что второй будет работать.

Однако в SQL Server 2008 есть синтаксис для вставки нескольких строк в один оператор INSERT , и я думаю, чтобыстрее, чем оба предложенных вами варианта:

INSERT INTO test (id, name)
VALUES
('1', 'foo'),
('2', 'bar'),
('3', 'baz')
 -- etc...

Однако, если вы действительно хотите высокую производительность, рассмотрите возможность использования класса SqlBulkCopy.

0 голосов
/ 22 ноября 2011

Второй, вероятно, быстрее, потому что в итоге вы получаете одну поездку туда и обратно. Оба одинаково ужасны, потому что вы не используете параметризованные запросы .

...