我正在查看SQL Server 2005上SP_WhoIsActive的输出,它告诉我一个会话正在阻止另一个会话 - 很好。但是他们都运行SELECT。 SELECT如何阻止另一个?他们不应该同时获取共享锁(彼此兼容)吗?
更多细节:两个会话都没有开放的交易计数 - 因此它们是独立的。
查询使用表格加入视图。
它们是复杂的查询,它们连接了大量的表,并导致大约10,000次读取。
非常感谢任何见解。
答案 0 :(得分:4)
SELECT语句可能会阻止另一个SELECT语句。你可能会认为既然两者都只获得S锁,它们就永远不会阻塞。但阻塞发生在各种类型的资源上,而不仅仅是锁。典型的例子是内存约束。我将尝试挖掘最近一个问题的答案,这个问题附加了一个向SELECT语句显示的死锁图,一个等待另一个用于并行交换运算符内存资源(缓冲区)。
<强>更新强> 以下是我所谈到的死锁信息的链接:I have data about deadlocks, but I can't understand why they occur 如果您研究死锁图,您会注意到等待列表中的以下资源:
<exchangeEvent id="Pipe894b0680" WaitType="e_waitPipeGetRow" nodeId="0">
<owner-list>
<owner id="process824df048"/>
</owner-list>
<waiter-list>
<waiter id="process86ce0988"/>
</waiter-list>
</exchangeEvent>
这不是一个锁,是一个'e_waitPipeGetRow'资源,由SELECT拥有,另一个SELECT正在等待它。有关“查询内并行资源”的一些讨论可以在这里找到:Today's Annoyingly-Unwieldy Term: "Intra-Query Parallel Thread Deadlocks"。虽然大多数讨论都将集中讨论死锁问题,但这并不意味着在这些资源上不会发生普通阻塞。 wait_type
wait_resource
和{{1}}将获得正确的信息。
答案 1 :(得分:0)
我认为它是因为第一个选择是执行行锁定/表锁定。在加入表格时,您可以提供无锁定提示。