如何避免SQL Server 2019在6000-10000数据量时批量更新导致表锁?

新手上路,请多包涵

数据库:SQLSERVER2019
描述:当数据库某表 A 总数据量在6000-10000时,测出来一个非常奇怪的现象,批量更新很少的数据就会导致锁升级为表锁,在执行批量更新前,没有有其他事务正在访问或修改表 A

--表结构
create table TESTUSER(
    ID INT NOT NULL,
    CREATTIME datetime,
    LASTTIME datetime,
    NAME NVARCHAR(20),
    AGE int,
    SEX NVARCHAR(6),
    ROW int,
    constraint PK_TESTUSER
        primary key (ID,NAME)
)
create index ROW_FK_CGRID
    on TESTUSER (ROW)
go
--更新(该表ID字段目前全是值2)
update YDHIS..TESTUSER SET AGE = '30' WHERE ID=2 AND NAME IN (SELECT TOP 500 NAME FROM YDHIS..TESTUSER WITH(NOLOCK) )

测试发现,表里面有一个是主键联合索引id + name,一个是单列的普通索引 row,更操作条件为WHERE id = 2 AND name in ( SELECT name from A WITH(NOLOCK) ),那么更新数量在50以上就会锁表

删除普通索引row,则不会出现该情况;
更操作条件为WHERE row in ( SELECT row from A WITH(NOLOCK) ),使用row索引也不会出现该情况。

这种情况只有数量表数据量在6000-10000时才会出现,不同的数据量区间(如小于6000或大于10000)都进行了相同的测试,结果是一样的,想问问各位大佬,这是什么原因导致的

阅读 413
1 个回答

分批更新

DECLARE @done BIT = 0;
WHILE (@done = 0)
BEGIN
    UPDATE TOP (100) YDHIS..TESTUSER
    SET AGE = '30'
    WHERE ID = 2 AND NAME IN (SELECT TOP 100 NAME FROM YDHIS..TESTUSER WITH(NOLOCK));
    IF @@ROWCOUNT < 100 SET @done = 1;
END;
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏