为什么在命令中执行多次插入比单次插入有显着的性能提升
我想插入大约 3000 条记录,当我使用方法 1 时,大约需要 2 分钟才能完成,但是如果我使用方法 2,插入将在不到一秒的时间内完成。虽然方法 2 不符合良好实践,但它给我带来了良好的性能增益。想了解为什么方法 1 需要这么多时间,是否有更好的方法来做到这
一点 方法 1:
public static void InsertModelValue(DataSet employeData, int clsaId)
{
var query = @"INSERT INTO employee (id, name)
VALUES (@id, @name)";
using (var connection = GetOdbcConnection())
{
connection.Open();
var tran = connection.BeginTransaction();
try
{
foreach (DataRow row in employeData.Tables[0].Rows)
{
using (var cmd = new OdbcCommand(query, connection, tran))
{
cmd.Parameters.Add("@id", OdbcType.VarChar).Value = row["ID"];
cmd.Parameters.Add("@name", OdbcType.Int).Value = Convert.ToInt32(row["Name"]);
cmd.ExecuteNonQuery();
}
}
tran.Commit();
}
catch
{
tran.Rollback();
throw;
}
}
}
方法 2:
public static void InsertModelValueInBulk(DataSet employeData, int clsaId, int batchSize)
{
string[] insertStatement = new string[batchSize];
using (var connection = GetOdbcConnection())
{
connection.Open();
var tran = connection.BeginTransaction();
try
{
int j = 0;
for (int i = 0; i < employeData.Tables[0].Rows.Count; i++)
{
var row = employeData.Tables[0].Rows[i];
var insertItem = string.Format(@"select '{0}',{1}", row["name"], Convert.ToInt32(row["ID"]);
insertStatement[j] = insertItem;
if (j % (batchSize-1) == 0 && j > 0)
{
var finalQuery = @" INSERT INTO employee (id, name)
" + String.Join(" union ", insertStatement);
using (var cmd = new OdbcCommand(finalQuery, connection, tran))
{
cmd.ExecuteNonQuery();
}
j = 0;
continue;
}
else
{
j = j + 1;
}
}
if (j > 0)
{
var finalQuery = @"INSERT INTO employee (id, name)
" + String.Join(" union ", insertStatement,0,j-1);
using (var cmd = new OdbcCommand(finalQuery, connection, tran))
{
cmd.ExecuteNonQuery();
}
}
tran.Commit();
}
catch
{
tran.Rollback();
throw;
}
}
}
I want to insert around 3000 records, when I go by approach 1 it takes around 2 min to complete, however if i use approach 2 insert completes in less than second. Though approach 2 doesn't adhere to good practice but its giving me good performance gain. Would like to understand why approach 1 takes so much time and can there be a better way to do this
Approach 1:
public static void InsertModelValue(DataSet employeData, int clsaId)
{
var query = @"INSERT INTO employee (id, name)
VALUES (@id, @name)";
using (var connection = GetOdbcConnection())
{
connection.Open();
var tran = connection.BeginTransaction();
try
{
foreach (DataRow row in employeData.Tables[0].Rows)
{
using (var cmd = new OdbcCommand(query, connection, tran))
{
cmd.Parameters.Add("@id", OdbcType.VarChar).Value = row["ID"];
cmd.Parameters.Add("@name", OdbcType.Int).Value = Convert.ToInt32(row["Name"]);
cmd.ExecuteNonQuery();
}
}
tran.Commit();
}
catch
{
tran.Rollback();
throw;
}
}
}
Approach 2:
public static void InsertModelValueInBulk(DataSet employeData, int clsaId, int batchSize)
{
string[] insertStatement = new string[batchSize];
using (var connection = GetOdbcConnection())
{
connection.Open();
var tran = connection.BeginTransaction();
try
{
int j = 0;
for (int i = 0; i < employeData.Tables[0].Rows.Count; i++)
{
var row = employeData.Tables[0].Rows[i];
var insertItem = string.Format(@"select '{0}',{1}", row["name"], Convert.ToInt32(row["ID"]);
insertStatement[j] = insertItem;
if (j % (batchSize-1) == 0 && j > 0)
{
var finalQuery = @" INSERT INTO employee (id, name)
" + String.Join(" union ", insertStatement);
using (var cmd = new OdbcCommand(finalQuery, connection, tran))
{
cmd.ExecuteNonQuery();
}
j = 0;
continue;
}
else
{
j = j + 1;
}
}
if (j > 0)
{
var finalQuery = @"INSERT INTO employee (id, name)
" + String.Join(" union ", insertStatement,0,j-1);
using (var cmd = new OdbcCommand(finalQuery, connection, tran))
{
cmd.ExecuteNonQuery();
}
}
tran.Commit();
}
catch
{
tran.Rollback();
throw;
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您想在您的银行帐户中存入三千美元。哪个更快:
还是
?
很明显,第一个比第二个慢很多。现在清楚为什么第一种技术比第二种技术慢数百倍了吗?
You want to deposit three thousand dollars in your bank account. Which is faster:
or
?
It should be fairly obvious that the first one is a lot slower than the second one. Now is it clear why the first technique is hundreds of times slower than the second?