我应该分解大型SQL查询(MS)

时间:2010-02-18 21:54:09

标签: sql sql-server-2005 tsql

这与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个更新查询或事情的事务?

5 个答案:

答案 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应包含足够的空间来容纳旧版本的记录,否则查询将失败。

如果您遇到任何一个问题,那么您应该将更新分成几个块。