如果值相同,SQL Server是否足够智能而不进行UPDATE



在工作中,我们一直在破解一个存储过程,我们注意到了一些问题。

对于我们的一个更新语句,我们注意到,如果这些值与以前的值相同,我们的性能就会提高。

我们不是说

UPDATE t1 SET A=5

其中列已经等于5。我们在做这样的事情:

UPDATE t1 SET A = Qty*4.3

不管怎样,如果UPDATE操作中的值计算结果相同,SQL Server是否足够聪明而不执行该操作,或者我只是被其他一些现象愚弄了?

是的,您将看到一些性能提升。我建议阅读这篇文章以更好地理解(它将比我更好地解释为什么):

https://sqlkiwi.blogspot.com/2010/08/the-impact-of-non-updating-updates.html

从TSQL的输出判断,即使UPDATE的值相同,它也会考虑执行UPDATE。

CREATE TABLE test (id INT, val int);
GO
INSERT INTO test VALUES(1, 1);
GO
(1 row(s) affected)
UPDATE test SET val=1 WHERE id=1;
GO
(1 row(s) affected)

当涉及到实际的磁盘写入时,我当然希望不需要它。

编辑:请参阅@AbeMiessler的答案,以获得更深入的分析,了解写入日志/磁盘部分的工作原理。

根据表索引的特定状态,您可能会看到一些性能提升。

如果表是索引的,并且更新不需要移动任何数据(集群)或不需要更改索引(非集群),那么您可能会看到收益。

如果你告诉SQL更新,它就会更新。因此,我将着眼于硬件方面(例如,索引)。

我必须运行自己的测试才能看到。我想和大家分享一下结果。

首先,yes,即使值相同,也会发生更新。

我创建了一个包含以下列的测试表:


上次更新时间

然后我插入:

INSERT INTO KeyValue VALUES ('TestKey1', 'TestValue1', GETDATE())

然后,我创建了一个触发器,在发生更新时更新LastUpdatedTime

CREATE TRIGGER UpdateLastUpdatedTime 
   ON  KeyValue
   AFTER UPDATE
AS 
BEGIN
    SET NOCOUNT ON;
    DECLARE @key VARCHAR(50) = (SELECT [Key] FROM INSERTED)
    UPDATE KeyValue SET LastUpdatedTime = GETDATE() WHERE [Key] = @key
END

然后我对一列进行了更新,并将其设置为与原来相同的值:

UPDATE KeyValue Set [Value] = 'TestValue1' WHERE [Key] = 'TestKey1'

LastUpdatedTime确实得到了更新,所以触发器被触发了。

现在,我想如果没有触发器,UPDATE可能不会发生,但我想它仍然会发生,特别是因为触发器是AFTER UPDATE

SQL在做其他事情之前必须实际计算数值结果,它必须这样做,这样它才能知道要用什么值"做某事"。即便如此,它也需要从表中读取值来进行比较。

我想说的是,如果是这样的话,实际上会降低读取值的效率,将其与您试图更新的值进行比较,然后决定是否应该提交更新操作。在您的情况下,它必须先读取Qty,然后才能计算出需要在A字段中输入的内容,但即便如此,当它比较值时,它也可能已经完成了更新,并继续繁忙的一天:)

最新更新