我试图准确地了解这里发生了什么。我意识到选择/更新组合可能会导致死锁 - 在这种情况下需要 longggg 等待。
场景是这个 Query A 是一个使用三个索引的 select 语句(非常简化)
select * from ProblemTable Where Plan_Id=@planId and
Date_entered Between @startDate and @endDate and nabp=@nabp
索引都是非聚集的:
- Plan_Id
- 日期_输入
- Plan_Id, nabp
都有 ProblemTable.Unique_Id 的“输出”
查询 B 是使用两个索引的更新语句
索引是:
- 非集群 Date_Entered ASC、源 ASC、DataStartOffset ASC
- 索引 1 的索引搜索结果中使用的 Unique_Id 上的聚集索引。
更新查询:
Update ProblemTable Set ProcessingTime=@processingTime
Where dateadd(dd, -datediff(dd, date_entered, 1), 1) =
dateadd(dd, -datediff(dd, getdate(), 1), 1)
and DateSource = 'xxyyzz' and DataStartOffset = 93148143
我知道.. dateadd 很傻。这不是我写的:)
因此,这会扫描与查询 A不同的索引,但也使用 Date_Entered。由于这种情况,长时间的等待不断发生。死锁似乎不会发生,但它可能会导致等待时间超过 5 分钟,其中每个查询通常以秒为单位执行。
请注意,这也发生在 INSERT into ProblemTable
所以 - 我猜 SELECT stmt 会在它最终根据 NC 索引搜索确定选择的行上获取锁,然后 update 语句会尝试在从 NC 索引上搜索返回的行上获取锁。但是为什么它只是花费了 longgggg 时间而没有发生死锁呢?
那么问题基本上是:
1 为什么等待时间长而不是死锁?2. 这是什么原因造成的?
这里有足够的信息吗?
编辑 1这两个查询都相当快,而且都不会花这么长的时间。长时间是这里“某些”未知锁定问题的结果。没有其他显式交易正在进行。