过度更新有多糟糕?

发布于 2024-11-19 15:57:57 字数 1236 浏览 2 评论 0原文

我有以下查询,我想知道 CASE 构造有多糟糕,它强制数据库引擎用 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;

也许将此 UPDATE 分成两个更便宜更新:

1

UPDATE E
SET E.EAOpID = @operationID
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
        AND E.EAOpID IS NULL -- Additional statement here
) AS E;

2

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;

I have the following query, I was wondering how bad is CASE construct, It forces DB Engine to overwrite E.EAOpID with the value that is already contained in E.EAOpID when it is not null

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;

Maybe it is cheaper to split this UPDATE into two UPDATES:

1

UPDATE E
SET E.EAOpID = @operationID
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
        AND E.EAOpID IS NULL -- Additional statement here
) AS E;

2

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

安人多梦 2024-11-26 15:57:57

即使没有值发生更改,更新行也只需要很少的资源。您可以通过检查更改来施加更多负载。当您的系统高度完善并且您接近边缘时,我可能会考虑这样的优化,但它在列表中的位置会很低。

Updating a row even if no values have changed involves very few resources. You could impose more load just by checking for the changes. You might I suppose consider an optimization like this when your system is highly refined and you're riding close to the edge, but it would be low on the list.

纸伞微斜 2024-11-26 15:57:57

两次更新将使用几乎两倍的资源,因为您将读取/更新同一组行。最好将所有内容都包含在一个查询中。我不知道如何衡量 case 语句需要多少额外处理,但我确实知道以下内容使用更少的编码逻辑执行相同数量的工作。将其从 更改

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)

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

Two updates would use almost twice as many resources, since you'd be reading/updating the same set of rows. Beter to have everything in one query. I don't know how to measure how much extra processing is required by the case statement, but I do know the following performs the same amount of work using less coding logic. Change it from

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

to

UPDATE E
 SET E.EAOpID = isnull(E.EAOpID, @operationID), 
 (etc)

(You can use coalesce instead of isnull if it makes you happy.)

仅此而已 2024-11-26 15:57:57

在表上使用的 SQL Server 功能越多,开销就越大,即使使用无操作更新也是如此。

操作和额外读取是在索引维护之外执行的。

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

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

The more features of SQL Server you use on the table, the more overhead there is, even with a no-op UPDATE.

Operations and extra reads are performed beyond index maintenance.

Triggers (triggers are fired), Foreign keys (integrity is still checked), Constraints (rules are checked), etc.

As an example: add a constraint to a table that would fail with some of the existing values, but using "WITH NOCHECK" to create. Update an existing column to itself; the update fails on the constraint even though the value did not change.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文