我正在分配一个用分号分隔的字符串INSERT
和UPDATES
to SqlCommmand.CommandText
,然后调用ExecuteNonQuery()
.
它“有效”,但我担心当字符串中有 40,000 个 INSERTS 时会发生什么。所有这些都发生在一个 SQL 事务中吗?我应该以某种方式对它们进行批量处理,批量应该有多大?
我正在分配一个用分号分隔的字符串INSERT
和UPDATES
to SqlCommmand.CommandText
,然后调用ExecuteNonQuery()
.
它“有效”,但我担心当字符串中有 40,000 个 INSERTS 时会发生什么。所有这些都发生在一个 SQL 事务中吗?我应该以某种方式对它们进行批量处理,批量应该有多大?
对于 40.000 次插入,您可能希望它们发生在单个事务中:这有利于性能,甚至更利于错误恢复(如果出现问题,您不会得到部分填充的表)。据我所知,它不会自动发生(即,如果您不启动一个事务,并且如果在数据库级别没有隐式打开事务(无论如何都需要显式提交),则没有事务)。
我建议使用带参数的准备好的查询,在循环中运行它,所有这些都在显式打开的事务中。
如果您有强大的插入值模式,请考虑使用用户定义的表类型。您可以将DataTable
参数作为参数传递给命令(自定义命令或存储过程)。
它比 CSV 更直接。
我同意@Anton Kovalenko - 如果您插入大量行,则应该立即执行。仅当您要插入超大(例如数百万)数量或行时,才将其拆分为多个批处理,但不要单独插入每一行。
对于 40.000 个插入,您希望它们在多个线程中处理的单独事务中。或者您希望它们使用 SqlBUlkCopy 发生在临时表中,而不是通过字符串插入。
基本上,创建一个临时表,sqlbulkcopy 到临时表中,用插入复制过来 select from。
这比所有 SQL 文本解析都要快很多。批处理 - 好吧,我经常在插入中执行接近 100.000 行的批处理。像这样的性能大约是每秒 75k 行。
这取决于您尝试在一个命令中发送的 ob 字节总数。我知道的唯一限制是批处理大小为 65,536 * 网络数据包大小(通常为 4096)= 268 435 456 字节 http://msdn.microsoft.com/en-us/library/ms143432.aspx