Sql 过度更新有多糟糕?

Sql 过度更新有多糟糕?,sql,sql-server,sql-server-2008,sql-optimization,Sql,Sql Server,Sql Server 2008,Sql Optimization,我有下面的查询,我想知道CASE构造有多糟糕,当它不为null时,它会强制DB引擎用E.EAOpID中已经包含的值覆盖E.EAOpID UPDATE E SET E.EAOpID = CASE WHEN E.EAOpID IS NULL THEN @operationID ELSE E.EAOpID END, E.AverageCapacity = E.AverageCapa

我有下面的查询,我想知道CASE构造有多糟糕,当它不为null时,它会强制DB引擎用E.EAOpID中已经包含的值覆盖E.EAOpID

UPDATE E
SET E.EAOpID =  CASE
                    WHEN E.EAOpID IS NULL THEN @operationID
                    ELSE E.EAOpID
                END,
    E.AverageCapacity = E.AverageCapacity + 1,
    E.Average = E.Average - (E.Average - E.Value) / E.AverageCapacity
FROM
(
    SELECT E.EAOpID, E.AverageCapacity, E.Average, P.Value
    FROM Probes AS P
    INNER JOIN Estimates AS E ON P.EstimateID = E.ID
    WHERE P.EAOpID = @operationID
) AS E;
将此更新拆分为两个更新可能更便宜:

1. 2.
表上使用的SQL Server功能越多,即使没有操作更新,开销也越大

操作和额外读取的执行超出了索引维护的范围

触发器(触发器已触发)、外键(完整性仍在检查)、约束(规则已检查)等


例如:向一个表中添加一个约束,该约束将因某些现有值而失败,但使用“with NOCHECK”创建。将现有列更新为自身;即使值没有更改,更新约束也会失败。

即使值没有更改,更新行所涉及的资源也很少。您可以通过检查更改来施加更多负载。我想假设你的系统是高度精炼的,并且你正接近边缘,但是它会在列表中很低。

< P>两个更新将使用几乎两倍的资源,因为你正在读取/更新同一行集合。最好在一个查询中包含所有内容。我不知道如何度量case语句需要多少额外的处理,但我知道下面的语句使用更少的编码逻辑执行相同的工作量。从

UPDATE E
 SET E.EAOpID =  CASE
                     WHEN E.EAOpID IS NULL THEN @operationID
                     ELSE E.EAOpID
                 END, 
 (etc)


(如果您满意,可以使用
coalesce
而不是
isnull

此表上的索引是什么样子的?为什么不使用探查器来衡量每个索引的性能。这确实是确定查询性能和读写次数的唯一方法。好的,我明白了,谢谢(目前没有索引,但添加它们不是问题,我关心的是理论问题)除了Randy关于测试的观点之外,我认为在很多情况下你会发现这一点(除非有许多索引引用该列),否则检查值是否不同的代价至少与不检查就覆盖它一样高——特别是如果您最终不得不在大量实例中覆盖它。关于“检查值是否不同”这不是关于速度,而是关于查询的逻辑,我需要检查它,因为我不希望它只在单独的情况下被更改。我还认为使用两个更新是更消耗资源的操作,顺便说一下,感谢ISNULL(…)。。。
UPDATE E
SET E.AverageCapacity = E.AverageCapacity + 1,
    E.Average = E.Average - (E.Average - E.Value) / E.AverageCapacity
FROM
(
    SELECT E.EAOpID, E.AverageCapacity, E.Average, P.Value
    FROM Probes AS P
    INNER JOIN Estimates AS E ON P.EstimateID = E.ID
    WHERE P.EAOpID = @operationID
) AS E;
UPDATE E
 SET E.EAOpID =  CASE
                     WHEN E.EAOpID IS NULL THEN @operationID
                     ELSE E.EAOpID
                 END, 
 (etc)
UPDATE E
 SET E.EAOpID = isnull(E.EAOpID, @operationID), 
 (etc)