我有一个存储过程,它通过覆盖索引从索引视图返回结果。通常,它运行得很快(~10 毫秒),有时它可以运行长达 8 秒。
这是一个随机执行示例(注意:这不是一个缓慢的执行,但是除了传递的值之外,查询文本是相同的):
declare @p2 dbo.IdentityType
insert into @p2 values(5710955)
insert into @p2 values(5710896)
insert into @p2 values(5710678)
insert into @p2 values(5710871)
insert into @p2 values(5711103)
insert into @p2 values(6215197)
insert into @p2 values(5710780)
exec ListingSearch_ByLocationAndStatus @statusType=1,@locationIds=@p2
Run Code Online (Sandbox Code Playgroud)
这是 SPROC:
ALTER PROCEDURE [dbo].[ListingSearch_ByLocationAndStatus]
@LocationIds IdentityType READONLY,
@StatusType TINYINT
AS
BEGIN
SET NOCOUNT ON;
SELECT -- lots of fields
FROM [dbo].[ListingSearchView][a] WITH (NOEXPAND)
INNER JOIN @LocationIds [b] ON [a].[LocationId] = [b].[Id]
WHERE [a].[StatusType] = @statusType
OPTION (RECOMPILE);
Run Code Online (Sandbox Code Playgroud)
(注意:我OPTION (RECOMPILE) …
performance sql-server sql-server-2012 azure-vm query-performance
在我们的实时服务器上发生了一些死锁,我知道,这很糟糕。
无论如何,我试图弄清楚如何查看导致锁定(或持有时间过长)的 SQL 代码。
我已经添加了所有的Locks事件(获得、死锁、升级、释放、超时等),但我所看到的只是对获得/释放事件的轰炸,没有太多附加信息。
我很确定我知道导致死锁的“场景”,因为我们在插入/更新/删除后在表上有一个触发器,这做了很多额外的工作,有时高达 8 秒。
但是,在大部分额外工作中,数据从 TableA 中提取并插入到表变量中,大量工作在该表变量的内存中进行(大约 6 秒过去),然后最终插入到 TableB 中。
问题: 即使我只是将某些行选择到表变量中,这实际上会导致整个表的表锁定吗?
我已经添加了“触发跟踪”(插入表 x 值('嗨,我在这里')等),我基本上知道这个过程花费的时间最长(因此必须可能导致锁定?)
但我仍然不确定为什么会发生僵局。
问题: 我可以看到发生了 2 个锁升级,这是否意味着行锁已升级为表锁?
问题: 有人能给我一些关于如何进一步追踪这个僵局的提示吗?
编辑:
这是死锁图
编辑2:
这是 [UpdatePostsCleanedUriUniqueUri] 的代码,这可能会导致表锁定?
ALTER PROC [dbo].[UpdatePostsCleanedUriUniqueUri]
(
@PostIds IdentityType READONLY
)
AS
SET NOCOUNT ON
-- *************************************************************************
-- ******************* Create the Cleaned Uri's, first ********************
-- *************************************************************************
---- "Remove" any existing cleaned uri's, per location
UPDATE a
SET …
Run Code Online (Sandbox Code Playgroud)