我将在这里留下我的答案,因为我能够测试不同的批量删除和更新方法(我必须更新然后删除超过125百万行,服务器有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
这种方法能够处理每小时更新约160万行和删除约20万行。
使用临时表会使情况发生很大变化。
deleteMore:
SELECT TOP 10000 Id
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
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
这个解决方案每小时处理约2500万行进行更新(速度提高了15倍),并且每小时处理约220万行进行删除(速度提高了11倍)。