【问题标题】:Does Persisted Computed Column need to update all rows or just affected rows?持久计算列需要更新所有行还是只更新受影响的行?
【发布时间】:2015-08-12 16:15:16
【问题描述】:

在这个Stackoverflow article 中,我明白了Persist 的含义以及它们的优缺点。但是,我尝试进行更深入的研究,但找不到有关“更新”的信息。

这是我的场景(TL;DR 版本如下):我有Order 表和OrderDetail 表,如下图所示:

OrderDetail.Subtotal 是一个计算列,具有以下简单公式:([Price]*[Quantity])

Order.Total 是一个计算列,公式为:([dbo].[CalculateOrderTotal]([ID])),函数如下:

ALTER FUNCTION [dbo].[CalculateOrderTotal]
(
    @orderID int
)
RETURNS int
AS
BEGIN
    DECLARE @result int;

    SELECT @result = SUM(od.Subtotal)
    FROM OrderDetail od
    WHERE od.OrderID = @orderID;

    RETURN @result;
END

TL;DR:我的OrderOrderDetail 经常更新,但主要是插入。我还需要经常查询它,尽管不像插入那么频繁。如果我检查我的SubtotalTotalPersist,由于大多数操作不会影响一行的Subtotal 字段,SQL Server 是否知道它,以便数据库只需要更新受影响的记录,还是必须重新计算Order 表的所有记录?是好是坏?

P.s:我使用的是 SQL Server 2008,以防万一。

【问题讨论】:

  • 我不确定你是否可以让 orders.total 保持不变。
  • @Tim3880 你是对的!我刚刚检查过,有一条消息:表 'Tmp_Order' 中的计算列 'Total' 无法持久化,因为该列是非确定性的。
  • 如果您想改进选择,请将总计设为普通列,并在您将行插入订单详细信息时对其进行更新。如果您想改进插入/更新,请创建一个 v_orders 视图,其中包括您需要的总数。
  • 感谢您的好建议!我打算这样做。

标签: sql-server performance sql-server-2008-r2 calculated-columns


【解决方案1】:

计算列在被选中时进行计算。
当计算它们的表达式发生更改时,将计算持久列。
因此,对于选择性能,我建议使用持久化,但对于存储空间不要使用持久化,因为“常规”计算列实际上并未存储在数据库中。

【讨论】:

  • 我需要澄清的是,如果进行了不会影响计算列值的更改(例如插入不会影响 Order.TotalOrderDetail 记录),请执行 SQL Server必须重新计算Order 表的所有记录?
  • AFAIK Sql server 只会重新计算实际需要重新计算的值。
猜你喜欢
  • 1970-01-01
  • 2019-11-20
  • 1970-01-01
  • 2011-06-11
  • 1970-01-01
  • 1970-01-01
  • 2020-10-05
  • 2013-10-27
相关资源
最近更新 更多