为什么更新子句更新主键索引

时间:2015-07-17 09:48:39

标签: sql sql-server deadlock

我有查询

DECLARE @ids TABLE (
    id BIGINT
);
DECLARE @dtDateLimit DATETIME;
SET @dtDateLimit = DATEADD(MINUTE, (-1) * @ResignTimeout, GETDATE());

UPDATE queue_local
SET [status] = @QueueLocalStatusToSign
OUTPUT INSERTED.id INTO @ids
WHERE [status] = @QueueLocalStatusSigning
AND status_date < @dtDateLimit;

根据执行计划,该子句更新主键索引(在列&#34; id&#34;)。 这种行为有原因吗?

我问,因为我在这个索引上遇到类似更新的死锁

UPDATE TOP (1) queue_local
SET [status] =
                CASE
                    WHEN @SignError IS NULL THEN @QueueLocalStatusSigned
                    ELSE @QueueLocalStatusError
                END
OUTPUT INSERTED.id INTO @ql_ids
WHERE task_sign_id = @ts_id
AND sono = @Sono
AND [status] = @QueueLocalStatusSigning

我尝试了解服务器行为

1 个答案:

答案 0 :(得分:0)

当你查看执行计划时。您是否看到运营商集群索引更新?如果您有一个包含聚簇索引的表,则聚簇索引会占用整个表。所以它总是需要更新。 另一方面,这并不意味着将更新聚簇索引KEY。如果在您的情况下,列[status]不是聚簇索引键的一部分,则只会为匹配的行更新聚簇索引的叶级别。 (如果没有页面拆分)。

如果[Status]列上有非聚簇索引,则SQL Server可以从那里查找聚簇索引的入口点(id)。