SQL Server:在迭代中合并

SQL Server:在迭代中合并,sql,sql-server,merge,sql-server-2017,Sql,Sql Server,Merge,Sql Server 2017,我必须将数百万行合并到一个表中。目标表具有更新后触发器。整个过程消耗的内存比我想要分配的要多得多,tempdb正在占用磁盘空间 我想让MERGE命令一次批量运行100000条记录。由于SET ROWCOUNT已被弃用,而且游标效率低下,我不确定这方面的最佳方法是什么。面向集合的方法将是高效运行查询的最佳方法。所以你所做的对我来说很好。如果它消耗tempdb等,则需要知道您是否正在执行任何正在减慢的逐行操作。一般来说,MERGE是一个单独的语句,因此是有效的 其他要考虑的是,如果在目标表上有索引,

我必须将数百万行合并到一个表中。目标表具有更新后触发器。整个过程消耗的内存比我想要分配的要多得多,tempdb正在占用磁盘空间


我想让MERGE命令一次批量运行100000条记录。由于SET ROWCOUNT已被弃用,而且游标效率低下,我不确定这方面的最佳方法是什么。

面向集合的方法将是高效运行查询的最佳方法。所以你所做的对我来说很好。如果它消耗tempdb等,则需要知道您是否正在执行任何正在减慢的逐行操作。一般来说,MERGE是一个单独的语句,因此是有效的

其他要考虑的是,如果在目标表上有索引,则可以删除这些索引,然后运行合并,然后重新创建索引。

对于您的问题,您可以使用mod操作符并在循环中运行MERGE,将其拆分为多个批

例如:

边尝试边循环

DECLARE @I INT = 1
WHILE (@I > 0)
BEGIN
    ;MERGE INTO Dst USING (
         SELECT TOP 1000
         FROM Src
         WHERE NotUpdated
    )
    ...
    
    SET @I = @@ROWCOUNT
END

为了避免重复合并相同的1000行,使用WHERE NotUpdated。在合并过程中,你会如何在SRC上暗示它?这取决于用例。您可以加入Dst表以检查行是否已更新。这个解决方案的优点是在循环期间向Src或Dst添加记录不会有问题。这是一个有趣的想法。问题:触发器是否会在循环的每次迭代执行后触发,或者(我担心)只有在整个事务运行后触发?我对其进行了测试,并且触发器会在循环的每次迭代中触发。我不认为用
合并
替换
更新
将如何改变触发器的性能。
DECLARE @I INT = 1
WHILE (@I > 0)
BEGIN
    ;MERGE INTO Dst USING (
         SELECT TOP 1000
         FROM Src
         WHERE NotUpdated
    )
    ...
    
    SET @I = @@ROWCOUNT
END