我想以最少的服务器开销删除大约 100,000 条记录。我遇到了一些无法正确测试的烦人问题,所以我想我会在这里问一些专家。哪个更好:
1-
BEGIN TRAN
DELETE FROM dbo.x
WHERE ID IN (
1
,2
,3
,4
...
,100000
)
COMMIT
2-
BEGIN TRAN
DELETE FROM dbo.x
WHERE ID = 1
GO
DELETE FROM dbo.x
WHERE ID = 2
GO
...
COMMIT
3-
DELETE FROM dbo.x
WHERE ID = 1
GO
DELETE FROM dbo.x
WHERE ID = 2
GO
...
我的假设是 #1 会根据样本 % 进行扫描,挑选出项目,删除它们,并将其记录为一系列事务。也许它会将事务日志中的信息作为更改页面而不是每个 indvl 的基础。事务,因此您只能回滚整个活动并重新标记页面,或者您可以提交。那是对的吗?
在 #2 上,我在想 GO 语句是否通过不允许 SQL Server 存储引擎将所有这些滚动到 1 个大事务中来导致更多的事务日志活动,但仍然使用 BEGIN TRAN 为事务日志提供一些优化- COMMIT 块,因此使其比#3 更有效但不如#1 有效。
然后我会假设#3 将是每个 indvl 中最糟糕的一个。交易记录。
如果有人有任何好的博客文章或测试场景,他们可以指出我那也很棒。我已经研究了深入挖掘事务日志以自己解决问题的方法,但在这一点上,我想我会问问你们。
谢谢!
从日志记录的角度来看,1 和 2 与您在单个事务中执行所有删除的两种情况大致相同。在运行删除时,会有很多锁定并可能阻塞。#3 是每批处理一个事务,因此用户不会受到太大影响,并且事务日志中会有很多小事务而不是一个大事务。#2 和#3 的运行时间应该差不多。#1 应该比 #2 和 #3 花费更少的时间,因为它只是一个命令,但是运行时间可能仍然会导致问题。
我可能想做这样的事情。这将通过一次只处理 1000 行来最大限度地减少需要发生的锁定和阻塞。