无法理解锁定逻辑

Mic*_*vko 1 sql-server locking sql-server-2014

在尝试创建死锁时,我遇到了无法理解的锁定问题:我正在更新按timekey列分区的大表: 在此处输入图片说明

我正在尝试运行两个更新语句:

BEGIN TRAN
    UPDATE [Transform].[AllCommunications_Arch] 
        SET Callid = 10300503454
    WHERE Callid = 10348103154
    AND TimeKey = 20161205
Run Code Online (Sandbox Code Playgroud)

BEGIN TRAN
    UPDATE [Transform].[AllCommunications_Arch] 
        SET Callid = 1234576704
    WHERE Callid = 4321276791
        AND TimeKey = 20160720
Run Code Online (Sandbox Code Playgroud)

每个人都应该更新一行,每个人都在不同的分区上运行,但由于某种原因,一个语句仍然阻塞另一个。DB 具有默认隔离杆(已提交读)。 在此处输入图片说明

执行计划: 在此处输入图片说明

CREATE TABLE [Transform].[AllCommunications_Arch](
    [SessionId] [varchar](100) NULL,
    [TimeKey] [int] NULL,
    [Callid] [bigint] NULL,
    [MemberId] [int] NULL,
    [Duration] [int] NULL,
    [CalledAt] [datetime] NULL,
    [EndTime] [datetime] NULL....
) ON [Transform_Timekey_Daily_Arch_PS]([TimeKey])
WITH
(
DATA_COMPRESSION = PAGE
)

GO

CREATE CLUSTERED INDEX [CL_Transform_AllCommunications_Arch] ON [Transform].[AllCommunications_Arch]
(
    [TimeKey] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, DATA_COMPRESSION = PAGE) ON [Transform_Timekey_Daily_Arch_PS]([TimeKey])
GO
Run Code Online (Sandbox Code Playgroud)

我已经LOCK_ESCALATION从默认更改tableauto现在它们不会相互阻止,但我仍然不明白为什么在这种情况下服务器会升级锁定。

Dan*_*man 5

我已将 LOCK_ESCALATION 从默认表更改为自动,现在它们不会相互阻塞,但我仍然不明白为什么在这种情况下服务器会升级锁。

这在SQL Server 联机丛书 CREATE TABLE 主题中特别提到。该笔记指出:

创建分区表后,请考虑将表的 LOCK_ESCALATION 选项设置为 AUTO。这可以通过使锁升级到分区 (HoBT) 级别而不是表来提高并发性。

默认表将升级到表级别,其中包括所有分区。

您还可以通过将 Callid 添加到聚集索引键并指定 unique 来提高此查询的并发性和性能。这将只涉及查询所需的单行,而不是使用排他锁扫描分区中的所有行。