我们可以减少索引上的行锁争用吗

The*_*war 2 sql-server locking blocking

我们很少有查询每 5 秒将它们的状态检查到一个表中并更新它们的状态。

下面是查询的样子(所有表列都在更新查询中)

update table1
set 
Name='somename'
DetailMessage='Error'
LastUpdate=getdate()
where id=14
Run Code Online (Sandbox Code Playgroud)

最近这个表遇到了阻塞问题,上面的更新查询是主要的阻塞器。当我运行时Sp_Blitzindex,它显示没有丢失的索引,284 分钟的行锁争用..

以下是我到目前为止所做的几个步骤.. 1.
确保外键被索引(它们也是主键)
2.为可以从新索引中受益的选择语句创建索引,以便减少对该索引的锁争用
3.我还将 Fillfactor 减少到 10,以前每页用于存储 93 行,现在它每页只存储 7 行(仍然无法给自己一个 100% 的逻辑解释,说明此更改将如何帮助...)

任何进一步的建议..如果您需要任何进一步的细节,请告诉我

下面是表的架构(更改的列名),表只有 350 行,查询以每 5 秒 20/30 次查询的频率更新此表...

create table dbo.table1
(
[ID] [int] NOT NULL,
[Name] [varchar](500) NULL,
[DetailMessage] [nvarchar](max) NOT NULL ,  
[LastUpdate] [datetime] NOT NULL
)
Run Code Online (Sandbox Code Playgroud)

PS:这是第三方查询,我们无法通过更改隔离级别等更改来修改源数据库...我只能添加索引

SQl 版本:SQl 2012

Jos*_*ell 7

如果此第三方应用程序持有这些行锁的时间足够长以引起争用,并且

  • 你无法改变这种行为,
  • 并且阻塞的查询是读取查询,然后

一种选择是在该数据库中启用 Read Committed Snapshot Isolation:

ALTER DATABASE [YourDatabaseName] 
SET READ_COMMITTED_SNAPSHOT ON;
Run Code Online (Sandbox Code Playgroud)

这应该会阻止这些UPDATE查询阻止您的读取查询。

请注意,这将影响读取查询的结果,因为它们将看到正在读取的数据的时间点快照,而不是被阻止等待更新。它还会增加 tempdb 的负载。有关实施 RCSI 的详细说明,请在此处查看 Kendra Little 的帖子:

在 SQL Server 中实现快照或读提交的快照隔离:指南