小编Sco*_*nJL的帖子

SQL Server - 有没有办法在使用索引视图时防止共享范围锁定为“无穷大”?

我有你的基本标题/细节表(想想订单和订单细节)。标题表有一个标识列作为聚集键,详细信息有一个标题 id 和一个行号列作为聚集键。header id 是一个不断增加的标识值,行号也是一个递增的值。

我试图在细节上添加一个索引视图来聚合数据,所以我们不必在代码中或通过触发器来做这件事,在现有系统中有它自己的一组并发问题。

在我们开始对其进行负载测试之前,一切看起来和工作正常。预计表中将添加约 1500 条详细信息/秒(90,000 条/分钟)。

当一行插入到明细表时,索引视图也会更新。在插入过程中,索引视图上出现共享范围锁 (RangeS-U)。取的范围是下一个键的当前键,类似于在可序列化隔离级别下获取锁的方式。连接是在已提交读下设置的。当表中不存在“下一个”键时,似乎会出现瓶颈。在这种情况下,共享锁被用于 'infinity(ffffffff)' 键。

这基本上描述了我看到的行为,但没有提供任何解决方法。 https://www.brentozar.com/archive/2018/09/locks-taken-during-indexed-view-modifications/

在上述负载下,服务器无法跟上插入的速度,并且事情开始备份得非常快。600 个并发连接中有 500 个在给定时间被阻塞。对不断增加的键的聚合索引视图似乎无法满足我们的并发要求。

我们使用的是 SQL Server 2012 标准版,很快就会升级到 2019。

有什么方法可以改变索引视图上的这种锁定行为,或者这对我来说是徒劳的,在这种情况下,我需要走基于代码/触发器的聚合之路,还是我错过了什么?如果 2019 没有表现出对我有用的行为,因为数据库将在工作完成之前升级。

包含的脚本代表所涉及的表,但显然不是实际的表。使用它们可以重现该行为。

设置

if object_id(N'dbo.LockTest') is null
begin
  create table dbo.LockTest
  ( LockTestID    int not null primary key
  , LockTestValue int     null
  );
  insert into dbo.locktest values(1, 1), (2, 2), (3, 3), (7, 7), (8, 8);
end;

if object_id(N'dbo.LockTestDetails') is null
begin
  create table dbo.LockTestDetails
  ( LockTestID  int not null
  , LineNumber …
Run Code Online (Sandbox Code Playgroud)

sql-server materialized-view locking

9
推荐指数
1
解决办法
561
查看次数

标签 统计

locking ×1

materialized-view ×1

sql-server ×1