SQL Server 2008 T-SQL 选择挂起,但未死锁

Ben*_*Ben 4 sql-server-2008 stored-procedures locking

这是一个非常奇怪的问题,所以请耐心等待。我有一个存储过程,可以进行一些繁重的处理。当它运行良好时,它通常需要几分钟的时间,具体取决于服务器负载,但有时它似乎卡住了。

我查看了 sp_who2 的结果,我看到该进程没有被阻塞,它仍然列为“RUNNABLE”,但磁盘 IO 中的值保持不变。一旦进程进入这种状态,它就永远不会完成。如果我终止进程并重新执行存储过程,我通常会得到相同的结果。

有时重新执行存储过程是可行的,但我最终不得不重新启动 SQL Server。不理想......重新启动后,存储过程按预期执行。有没有人遇到过这样的问题?任何建议将不胜感激。

更多的上下文。我正在执行的存储过程如下所示:

delete
from table1

insert into table1
select columns
from 
(
    select columns
    from giant_table_1 WITH (NOLOCK)
    where condition
    group by columns

    UNION

    select columns
    from giant_table_2 WITH (NOLOCK)
    where condition
    group by columns
)
where condition

more crud on table1
.
.
.
Run Code Online (Sandbox Code Playgroud)

如果我将一些日志语句插入到存储过程中,我可以看到它挂起时它挂在插入/选择上。想知道这是否可能是 NOLOCK 语句的奇怪结果。我们(我的意思是我的老板 :))添加了 nolock,因为 Giant_table_1 和 Giant_table_2 不断变化。如果没有 nolock,我们的 sproc 会被其他长时间运行的进程阻塞很多,反之亦然。

提前致谢!

Mar*_*inC 5

从您查询的外观来看,我相信该进程正在等待溢出到 tempdb。您将需要查看输出

SELECT * FROM sys.dm_os_waiting_tasks WHERE session_id = <SPID for the SP>
Run Code Online (Sandbox Code Playgroud)

为了更好地了解后台发生的事情,Adam Machanic 的sp_whoisactive是一个很好的工具,用于简化有关查询执行的详细信息的收集。

还要确保为您的数据库和 tempdb 正确设置了自动增长,并为数据和日志设置了合理的自动增长量,并且日志文件中的 VLF 数量低于 100。查看他的帖子了解详细信息8 Steps to Better Transaction Log吞吐量