为什么行数增加但最大 id 没有改变?

Why is the row count increasing but the max id does not change?

这……很有趣。我正在尝试删除 table 中的一堆记录(约 200 万条)。在等待大约 4 个小时完成简单的删除后,我开始调查。

delete from mytable where date > getutcdate()

如果我执行一些计数查询,总行数会增加,但最大 ID(身份)不会改变。

select count(1) from mytable with(nolock)
select max(Id) from mytable with(nolock) 

我通过终止所有不是来自我的 IP 地址的会话来确保只有打开的连接。

select * from sys.dm_exec_connections
kill 123
kill 124
kill 125
-- etc

然而,总行数增加了,最大 Id 保持不变。到底是什么原因导致的??

更新

看来我的原始查询仍然是 运行ning。我发誓我已经杀死了它,但如果我现在尝试杀死它,它会显示 "Command(s) completed successfully",但如果我再次 运行 此查询,它仍然显示为 运行ning:

SELECT * 
FROM sys.dm_exec_sessions s
LEFT JOIN sys.dm_exec_connections c
     ON  s.session_id = c.session_id
LEFT JOIN sys.dm_db_task_space_usage tsu
     ON  tsu.session_id = s.session_id
LEFT JOIN sys.dm_os_tasks t
     ON  t.session_id = tsu.session_id
          AND t.request_id = tsu.request_id
LEFT JOIN sys.dm_exec_requests r
     ON  r.session_id = tsu.session_id
         AND r.request_id = tsu.request_id
OUTER APPLY sys.dm_exec_sql_text(r.sql_handle) TSQL 

更新 2

行数终于停止上升,并且释放了锁,所以它确实回滚了几个小时。在今晚刚好在线(美国东部时间凌晨 2 点)的老板的帮助下,我们重建了一些索引并尝试了不同的方法。

DELETE_MORE:
    DELETE TOP(5000) from mytable where date > getutcdate()
IF @@ROWCOUNT > 0 GOTO DELETE_MORE

是的,这是一个 GOTO。是的,这是我在职业生涯中发现使用它的唯一原因。现在这已经不存在了……这将删除 5000 组中的行,如果失败则最大限度地减少锁定和回滚。这似乎运作良好,因为它是 运行ning 当我输入这个时。

如果您完全排除了其他人修改 table 的可能性,那么回滚很可能仍在完成。使用 nolock 查询 table 会绕过锁定,因此您可以读取正在回滚的数据,并且它可能已经开始以最大 ID 向后回滚。尝试在没有 nolock 的情况下执行计数查询。打开一个新会话并执行 sp_who2 和 sp_lock 以查看您的查询是否被阻止。执行 sp_who2 还将显示是否有 spid 执行回滚。使用 statusonly 执行 kill #spid 以获得更多信息。