为什么行数增加但最大 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 以获得更多信息。
这……很有趣。我正在尝试删除 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 以获得更多信息。