C# ADO.net SqlTransaction提高了性能

C# ADO.net SqlTransaction提高了性能,c#,sql-server,ado.net,C#,Sql Server,Ado.net,我正在做一些工作,包括将一批记录插入Sql数据库。批处理的大小会有所不同,但为了便于讨论,我们可以说每5秒有5000条记录。不过,情况可能会有所好转。多个进程将写入此表,但没有从中读取任何内容 我在快速测试中注意到,围绕整个批插入使用SqlTransaction似乎可以提高性能 e、 g 我对回滚更改的功能不感兴趣,因此我不会真正考虑使用事务,除非它似乎可以提高性能。如果我删除这个事务代码,我的插入将从300ms增加到800ms左右 这是什么逻辑?因为我的理解是,事务仍然会将数据写入数据库,但会

我正在做一些工作,包括将一批记录插入Sql数据库。批处理的大小会有所不同,但为了便于讨论,我们可以说每5秒有5000条记录。不过,情况可能会有所好转。多个进程将写入此表,但没有从中读取任何内容

我在快速测试中注意到,围绕整个批插入使用SqlTransaction似乎可以提高性能

e、 g

我对回滚更改的功能不感兴趣,因此我不会真正考虑使用事务,除非它似乎可以提高性能。如果我删除这个事务代码,我的插入将从300ms增加到800ms左右

这是什么逻辑?因为我的理解是,事务仍然会将数据写入数据库,但会锁定记录,直到提交为止。我本以为这会有一笔开销


我正在寻找的是最快的方式做这个插入

提交需要花费时间。如果没有显式事务,则每个查询执行一个事务。使用显式事务时,不会为查询创建其他事务。因此,您有一个事务和多个事务。这就是性能改进的来源。

如果您正在寻找插入/加载数据的快速wqay,请查看一下您得到的是完全正常的

如果您使用的是通常的隔离级别(比如Committed或snapshot),那么当您不使用事务时,数据库引擎必须在每次插入时检查冲突。也就是说,它必须确保每当有人从该表中读取(例如,使用
选择*
)时,它不会得到脏读,也就是说,保持插入,以便在插入本身时,没有其他人在读取

这意味着,锁定、插入行、解锁、锁定、插入行、解锁等等


当您将所有这些都封装到事务中时,您实际上实现的是在提交阶段将一系列“锁定”和“解锁”减少为一个。

我刚刚完成了一篇关于通过明确指定事务开始和结束的位置可以获得的性能提升的文章


使用Dapper,我观察到事务将批插入时间减少到原始时间的1/2,批更新时间减少到原始时间的1/3

如果您仅向其写入,还可以指定
trans.IsolationLevel=IsolationLevel.Chaos
(最低级别)因此,您的事务不会锁定其他并发事务;回滚是最昂贵的一个。我认为在设置大量事务时确实会有开销,但在开始时,不是结束IIRC。我想这种方法的缺点是在事务期间表被锁定?如果多个进程试图写入这个表,这些事务会被有效地排队或是不需要,因为这些插入件从不更新或删除现有行吗?需要锁定表,因为SELECT*影响需要所有行,不能在中间中断。无论如何,这并不意味着要花很长时间。我不知道任何具体的实现,但可以想象,您可以构造一个表的内存副本,然后在内存不足时交换,这将非常快。SqlBulkCopy的问题是您需要了解表结构。我同意这是最快的方法,尽管差距很大。
SqlTransaction trans = Connection.BeginTransaction()
myStoredProc.Transaction = trans;
sampleData.ForEach(ExecuteNonQueryAgainstDB);
transaction.Commit();