这与MS SQL Server 2005有关。
我有一个SSIS包,用于验证两个不同数据源之间的数据。如果找到差异,它会构建并执行SQL更新脚本来解决问题。在找到所有差异后,SQL Update脚本将在包的末尾运行。
我想知道是否有必要或者一个好主意如何将sql更新脚本分解为多个事务,最好的方法是什么。
更新脚本看起来与此类似,但更长(示例):
Update MyPartTable SET MyPartGroup = (Select PartGroupID From MyPartGroupTable
Where PartGroup = "Widgets"), PartAttr1 = 'ABC', PartAttr2 = 'DEF', PartAttr3 = '123'
WHERE PartNumber = 'ABC123';
对于发现的每个错误/差异,都会向更新脚本添加其他更新查询。 我每天只期待大约300次更新,但有时可能会有50,000次更新。我是否应该将脚本分解为每个说500个更新查询或事情的事务?
答案 0 :(得分:2)
不,我认为声明很好。它根本不会产生很大的速度差异。 如果你关心查询的可读性,Billy会提出一个有效的观点(如果它是将来会看到或使用的查询,你应该这样做。)。
答案 1 :(得分:2)
在您知道存在问题之前不要优化任何内容。如果它运行得很快,就放手吧。如果运行缓慢,请进行一些更改。
答案 2 :(得分:1)
将事情分开应该不是问题。但是,如果您希望A.保持项目之间的一致性,和/或B.执行得更好,您可能希望使用单个事务来处理事情。
BEGIN TRANSACTION;
//Write 500 things
//Write 500 things
//Write 500 things
COMMIT TRANSACTION;
交易存在就是出于这个原因 - 程序逻辑通过拆分查询更清晰,但需要多个操作之间的数据一致性。
答案 3 :(得分:1)
您的系统会处理读取尚未更新的数据的其他进程吗?如果是这样,您可能想要执行多个事务。
执行多个事务的好处是您不会不断累积锁。如果您一次执行所有这些更新,SQL Server最终将耗尽小粒度锁资源(行/键)并升级到表锁。当它执行此操作时,除非他们使用脏读或处于快照模式,否则没有其他人能够从这些表中读取(除非他们使用脏读或处于快照模式)。
副作用是读取数据的其他进程可能会得到不一致的结果。
因此,如果nodoby在您更新时需要使用此数据,那么请确保在一个事务中执行所有更新。如果还有其他进程需要使用该表,那么是的,以块的形式进行。
答案 4 :(得分:1)
如果事务在tempdb
隔离级别运行,则受查询影响的所有记录都将被锁定或复制到SNAPSHOT
。
如果记录数足够高,锁可能会升级。
如果事务隔离级别不是SNAPSHOT
,则并发查询将无法读取可能是应用程序并发问题的锁定记录。
如果事务隔离级别为SNAPSHOT
,则tempdb
应包含足够的空间来容纳旧版本的记录,否则查询将失败。
如果您遇到任何一个问题,那么您应该将更新分成几个块。