我正在做一些涉及将一批记录插入Sql数据库的工作。批量的大小会有所不同,但为了论证,我们可以说每5秒有5000条记录。但可能会少一些。多个进程将写入此表,没有任何内容正在从中读取。
在快速测试期间我注意到,在整个批量插入中使用SqlTransaction似乎可以提高性能。
e.g。
SqlTransaction trans = Connection.BeginTransaction()
myStoredProc.Transaction = trans;
sampleData.ForEach(ExecuteNonQueryAgainstDB);
transaction.Commit();
我对能够回滚我的更改不感兴趣所以我不会真正考虑使用事务,除非它似乎提高了性能。如果我删除此事务代码,我的插入将从300毫秒到大约800毫秒!
这是什么逻辑?因为我的理解是事务仍然将数据写入数据库但锁定记录直到它被提交。我原以为这会有一个开销......
我正在寻找的是这种插入的最快方法。
答案 0 :(得分:8)
提交是花费时间的。如果没有显式事务,则每个查询执行一个事务。使用显式事务,不会为查询创建其他事务。因此,您有一个交易与多个交易。这就是性能改进的来源。
答案 1 :(得分:5)
如果您正在寻找快速插入/加载数据的方法,请查看SqlBulkCopy Class
答案 2 :(得分:3)
你得到的是完全正常的。
如果您使用通常的隔离级别(比如提交或快照),那么当您不使用事务时,数据库引擎必须在每次插入时检查冲突。也就是说,它必须确保每当有人从该表读取时(例如SELECT *
),它不会得到脏读,也就是说,保留插入以便插入本身时它正在发生没人在读。
这意味着,锁定,插入行,解锁,锁定,插入行,解锁等等。
当您在事务中封装所有内容时,您实际上正在实现的是在提交阶段将“锁定”和“解锁”系列减少为一个。
答案 3 :(得分:1)
我刚刚通过明确指定事务开始和结束的位置,写了一个blog post来获得性能提升。
使用Dapper我观察到交易将批量插入减少到原始时间的1/2并且批量更新时间减少到原始时间的1/3