我将在这里留下我的答案,因为我能够测试批量删除和更新的不同方法(我必须更新然后删除 125+mio 行,服务器有 16GB 的 RAM,Xeon E5-2680 @2.7GHz,SQL Server 2012)。
TL;DR:始终按主键更新/删除,从不按任何其他条件。如果您不能直接使用 PK,请创建一个临时表并用 PK 值填充它,然后使用该表更新/删除您的表。为此使用索引。
我从上面的解决方案开始(@Kevin Aenmey),但这种方法被证明是不合适的,因为我的数据库是实时的,它每秒处理几百个事务并且涉及一些阻塞(所有的索引都有条件中的字段,使用WITH(ROWLOCK)
没有改变任何东西)。
因此,我添加了一条WAITFOR
语句,允许数据库处理其他事务。
deleteMore:
WAITFOR DELAY '00:00:01'
DELETE TOP(1000) FROM MyTable WHERE Column1 = @Criteria1 AND Column2 = @Criteria2 AND Column3 = @Criteria3
IF @@ROWCOUNT != 0
goto deleteMore
这种方法能够处理约 1.6mio 行/小时的更新和约 0.2mio 行/小时的删除。
转向临时表改变了很多事情。
deleteMore:
SELECT TOP 10000 Id /* Id is the PK */
INTO #Temp
FROM MyTable WHERE Column1 = @Criteria1 AND Column2 = @Criteria2 AND Column3 = @Criteria3
DELETE MT
FROM MyTable MT
JOIN #Temp T ON T.Id = MT.Id
/* you can use IN operator, it doesn't change anything
DELETE FROM MyTable WHERE Id IN (SELECT Id FROM #Temp)
*/
IF @@ROWCOUNT > 0 BEGIN
DROP TABLE #Temp
WAITFOR DELAY '00:00:01'
goto deleteMore
END ELSE BEGIN
DROP TABLE #Temp
PRINT 'This is the end, my friend'
END
此解决方案处理约 25mio 行/小时的更新(快 15 倍)和约 2.2mio 行/小时的删除(快 11 倍)。