为什么使用 SqlCommand 插入语句很慢?
Why insert statement is slow with SqlCommand?
我正在使用Sql命令向数据库中插入多条记录,但是插入2000条记录需要很长时间,我做了以下代码:
using (SqlConnection sql = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand(query, sql))
{
sql.Open();
int ff = 0;
while (ff < 2000)
{
cmd.ExecuteNonQuery();//It takes 139 milliseconds approximately
ff++;
Console.WriteLine(ff);
}
}
}
但是当我在 SSMS(Sql Server Management Studio) 中执行以下脚本时,2000 条记录会在 15 秒内存储:
declare @i int;
set @i=1
while (@i)<=2000
begin
set @i=@i+1
INSERT INTO Fulls (ts,MOTOR,HMI,SET_WEIGHT) VALUES ('2018-07-04 02:56:57','0','0','0');
end
这是怎么回事?
为什么执行语句这么慢?
补充:
-数据库是 SQL Microsoft Azure 中托管的数据库。
-我的网络加载速度是 20 Mbits。
-上述查询不是真正的查询,真正的查询包含240列和240个值。
-我尝试按照以下示例进行交易:https://msdn.microsoft.com/en-us/library/86773566(v=vs.110).aspx
-sql 变量的类型为 SqlConnection。
感谢您的帮助。
听起来您的 SQL 服务器和应用程序服务器之间存在高延迟。当我在本地执行此操作时,纯 TSQL 版本运行 363 毫秒,而具有 2000 次往返的 C# 版本需要 1061 毫秒(因此:每次往返约 0.53 毫秒)。注意:我把 Console.WriteLine
拿走了,因为我不想测量 Console
有多快!
对于 2000 个插入,这是一个相当公平的比较。如果您看到的是截然不同的东西,那么我怀疑:
- 您的 SQL 服务器严重不足 - 它应该 而不是 需要 15 秒(根据问题)插入 2000 行,在 any 情况(我的 363ms 计时是在我的台式电脑上,而不是快速服务器)
- 如前所述;你有高延迟
请注意,还有 "DTC" 之类的东西可能会影响基于连接字符串和环境事务 (TransactionScope
) 的性能,但我假设这些不是这里的因素。
如果你需要提高这里的性能,首先要做的是找出为什么它如此糟糕 - 即原始服务器性能是糟糕,延迟巨大。这些都不是编码问题:那些是基础设施问题。
如果您无法解决这些问题,那么您可以围绕它们进行编码。 Table 值参数或批量插入 (SqlBulkCopy
) 都提供了传输多行的方法,而无需为每次执行支付往返费用。您还可以使用 "MARS"(多个活动结果集)和流水线插入,但这是一个相当高级的主题(大多数人倾向于建议不要启用 MARS)。
确保尽量减少 table 上的索引数量并按如下方式使用 SqlBulkCopy
DataTable sourceData=new DataTable();
using (var sqlBulkCopy = new SqlBulkCopy(_connString))
{
sqlBulkCopy .DestinationTableName = "DestinationTableName";
sqlBulkCopy .WriteToServer(sourceData);
}
我正在使用Sql命令向数据库中插入多条记录,但是插入2000条记录需要很长时间,我做了以下代码:
using (SqlConnection sql = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand(query, sql))
{
sql.Open();
int ff = 0;
while (ff < 2000)
{
cmd.ExecuteNonQuery();//It takes 139 milliseconds approximately
ff++;
Console.WriteLine(ff);
}
}
}
但是当我在 SSMS(Sql Server Management Studio) 中执行以下脚本时,2000 条记录会在 15 秒内存储:
declare @i int;
set @i=1
while (@i)<=2000
begin
set @i=@i+1
INSERT INTO Fulls (ts,MOTOR,HMI,SET_WEIGHT) VALUES ('2018-07-04 02:56:57','0','0','0');
end
这是怎么回事? 为什么执行语句这么慢?
补充:
-数据库是 SQL Microsoft Azure 中托管的数据库。
-我的网络加载速度是 20 Mbits。
-上述查询不是真正的查询,真正的查询包含240列和240个值。
-我尝试按照以下示例进行交易:https://msdn.microsoft.com/en-us/library/86773566(v=vs.110).aspx
-sql 变量的类型为 SqlConnection。
感谢您的帮助。
听起来您的 SQL 服务器和应用程序服务器之间存在高延迟。当我在本地执行此操作时,纯 TSQL 版本运行 363 毫秒,而具有 2000 次往返的 C# 版本需要 1061 毫秒(因此:每次往返约 0.53 毫秒)。注意:我把 Console.WriteLine
拿走了,因为我不想测量 Console
有多快!
对于 2000 个插入,这是一个相当公平的比较。如果您看到的是截然不同的东西,那么我怀疑:
- 您的 SQL 服务器严重不足 - 它应该 而不是 需要 15 秒(根据问题)插入 2000 行,在 any 情况(我的 363ms 计时是在我的台式电脑上,而不是快速服务器)
- 如前所述;你有高延迟
请注意,还有 "DTC" 之类的东西可能会影响基于连接字符串和环境事务 (TransactionScope
) 的性能,但我假设这些不是这里的因素。
如果你需要提高这里的性能,首先要做的是找出为什么它如此糟糕 - 即原始服务器性能是糟糕,延迟巨大。这些都不是编码问题:那些是基础设施问题。
如果您无法解决这些问题,那么您可以围绕它们进行编码。 Table 值参数或批量插入 (SqlBulkCopy
) 都提供了传输多行的方法,而无需为每次执行支付往返费用。您还可以使用 "MARS"(多个活动结果集)和流水线插入,但这是一个相当高级的主题(大多数人倾向于建议不要启用 MARS)。
确保尽量减少 table 上的索引数量并按如下方式使用 SqlBulkCopy
DataTable sourceData=new DataTable();
using (var sqlBulkCopy = new SqlBulkCopy(_connString))
{
sqlBulkCopy .DestinationTableName = "DestinationTableName";
sqlBulkCopy .WriteToServer(sourceData);
}