SQL Server+循环插入性能
本文关键字:性能 插入 循环 Server+ SQL | 更新日期: 2023-09-27 18:01:07
我正在进行如下所示的循环插入(方法a(,似乎用每个循环调用数据库不是一个好主意。我发现一个替代方案是在我的SProc中循环一个逗号分隔的字符串,而不是进行插入,这样数据库中就只有一个条目。在性能方面会有任何显著的改进吗?:
方法A:
foreach (DataRow row in dt.Rows)
{
userBll = new UserBLL();
UserId = (Guid)row["UserId"];
// Call userBll method to insert into SQL Server with UserId as one of the parameter.
}
方法B:
string UserIds = "Tom, Jerry, 007"; // Assuming we already concatenate the strings. So no loops this time here.
userBll = new UserBLL();
// Call userBll method to insert into SQL Server with 'UserIds' as parameter.
方法B SProc/在SProc中执行循环插入
if right(rtrim(@UserIds ), 1) <> ','
SELECT @string = @UserIds + ','
SELECT @pos = patindex('%,%' , @UserIds )
while @pos <> 0
begin
SELECT @piece = left(@v, (@pos-1))
-- Perform the insert here
SELECT @UserIds = stuff(@string, 1, @pos, '')
SELECT @pos = patindex('%,%' , @UserIds )
end
更少的查询通常意味着更快的处理。也就是说,我的一位同事在这方面取得了一些成功。NET Framework的TSQL BULK INSERT
包装器,该包装器由Framework提供为SqlBulkCopy
。这个MSDN博客展示了如何使用它。
主要的"API"示例如下(取自链接文章as-is,它将DataTable的内容写入SQL(:
private void WriteToDatabase()
{
// get your connection string
string connString = "";
// connect to SQL
using (SqlConnection connection =
new SqlConnection(connString))
{
// make sure to enable triggers
// more on triggers in next post
SqlBulkCopy bulkCopy =
new SqlBulkCopy
(
connection,
SqlBulkCopyOptions.TableLock |
SqlBulkCopyOptions.FireTriggers |
SqlBulkCopyOptions.UseInternalTransaction,
null
);
// set the destination table name
bulkCopy.DestinationTableName = this.tableName;
connection.Open();
// write the data in the "dataTable"
bulkCopy.WriteToServer(dataTable);
connection.Close();
}
// reset
this.dataTable.Clear();
this.recordCount = 0;
}
链接的文章解释了利用这一机制需要做些什么。
根据我的经验,有三件事你不想为每条记录做:
-
每行打开/关闭一个sql连接。这个问题由ADO处理。NET连接池。除非您禁用了池,否则您不必担心它。
-
每行的数据库往返。这往往与网络带宽或网络延迟无关,而与客户端线程睡眠有关。每次客户端醒来时,你都需要在客户端上做大量的工作,或者你在浪费时间。
-
按行打开/关闭sql事务日志。打开和关闭日志不是免费的,但你也不想打开太久。在一个事务中执行多个插入,但不要太多。
对于其中的任何一个,您可能会看到从每个请求1行到每个请求10行的许多改进。您可以通过在传输批处理之前在客户端构建10个插入语句来实现这一点。
Sommarskog已经对你将列表发送到进程中的方法进行了深入的研究。
如果您想在给定类型的多个输入值中获得更好的插入性能,我建议您查看表值参数。
这里可以找到一个示例,显示了一些使用它们的示例代码。
您可以为此使用批量插入功能。
有关详细信息,请参阅此博客:http://blogs.msdn.com/b/nikhilsi/archive/2008/06/11/bulk-insert-into-sql-from-c-app.aspx