1

我正在使用 Microsoft SQL Server。我想存储/缓存昂贵的计算,以便可以重用它们。在我的示例中,我有由用户评分的项目,数据库架构如下所示:

User
 Id : int

Item
 Id : int

UserItemRating
 UserId (User)
 ItemId (Item)
 Rating : int

为了获得评分最高的项目,我需要计算每个项目的平均评分(假设操作很昂贵并且 UserItemRating 经常更改/更新)。缓存此计算的好方法是什么?我应该向 Item 添加一列“AverageRating”并创建一个更新它的触发器吗?创建视图?保存计算的临时表?

4

1 回答 1

3

在 SQL Server 中,您将创建一个索引视图,如下所示:

create view dbo.ItemRatings
with schemabinding
as
    select
        ItemId,
        COUNT_BIG(*) as Cnt,
        SUM(Rating) as TotalRating
    from
        dbo.UserItemRating
    group by
        ItemId
go
create unique clustered index IX_ItemRatings on dbo.ItemRatings (ItemId)

索引视图的创建和使用有各种限制,但以上是有效的(假设UserItemRating是在dbo模式中)。

注意事项:

  1. 必须是WITH SCHEMABINDING,这反过来意味着我们必须使用两部分名称来引用表。
  2. 必须使用COUNT_BIG()才能使用GROUP BY子句
  3. 不直接包含平均值(实际上,索引视图中不允许使用),但是,您可以通过将.AVG除以.SUM()COUNT_BIG()
  4. 要使用此视图上的索引,您需要使用NOEXPAND提示查询它,或者运行 Enterprise Edition 或更高版本。

为什么这比基于触发器/表的解决方案更受欢迎?因为执行维护的代码是内置在SQL Server 中的,与任何其他解决方案相比,总开销会更低。(而且您不必花时间确保它是正确的)

如果您使用的是企业版,它甚至可以在您的查询不直接引用它的情况下使用这个索引视图——例如,如果您要对请求 、 甚至 的基表进行查询COUNTSUMAVG可能会使用这个指数。

于 2013-07-23T06:13:27.127 回答