过度更新有多糟糕?
我有以下查询,我想知道 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
即使没有值发生更改,更新行也只需要很少的资源。您可以通过检查更改来施加更多负载。当您的系统高度完善并且您接近边缘时,我可能会考虑这样的优化,但它在列表中的位置会很低。
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.
两次更新将使用几乎两倍的资源,因为您将读取/更新同一组行。最好将所有内容都包含在一个查询中。我不知道如何衡量 case 语句需要多少额外处理,但我确实知道以下内容使用更少的编码逻辑执行相同数量的工作。将其从 更改
为
(如果您满意,您可以使用
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
to
(You can use
coalesce
instead ofisnull
if it makes you happy.)在表上使用的 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.