2

对于给定的时间点,资产具有有效价格。有些资产每周有一次新价格,有些则每天一次。最近的价格是“有效价格”。

存储所描述关系的时态表如下所示:

CREATE TABLE dbo.AssetPrice
(
    AssetId int NOT NULL -- FK to the table dbo.Asset
    ,EffectiveDate datetime NOT NULL
    ,Price decimal NOT NULL
    CONSTRAINT PK_AssetPrice PRIMARY KEY CLUSTERED (AssetId,EffectiveDate,Price)
)

数据看起来像这样:

AssetId    EffectiveDate    Price
-------    -------------    -----
      1       2012-01-11     1.21
      1       2012-01-12     1.22
      2       2012-01-11     3.55
      2       2012-01-12     3.60
      3       2012-01-04     5.15
      3       2012-01-11     5.14

查询一个的有效价格AssetId很简单,但计算起来需要大量的时间。

物理存储数据是理想的,因此只有数据更改为dbo.AssetPrice需要重新计算有效价格。我相信我无法创建索引视图,因为索引视图中不允许相关的聚合函数。

如何调整表格以快速检索有效价格(最新价格)?

4

1 回答 1

2

基本上你可以使用两种不同的方法:

  • 更改表架构以包含间隔。在这种情况下,您需要存储开始和结束日期以确定您的有效期。有了这个,您只需要使用一个简单的 BETWEEN 即可获得您想要的价格。您还可以在开始和结束日期以及 AssetId 上添加非聚集索引以获得最佳性能。默认情况下,您可以将结束日期添加为“9999-12-31”,并且每次资产有新价格时,您都会结束当前期间并开始新的期间。我(个人)更喜欢这个选项。

  • 坚持使用此架构并在 EffectiveDate 和 AssetId 上创建一个非聚集索引。您需要构建一个子选择以获取生效日期小于您所需日期的资产的最大日期,如下所示:

.

CREATE INDEX    IX_AssetPrice_EffectiveDate
                ON AssetPrice (EffectiveDate, AssetId) INCLUDE (Price)
DECLARE @AssetId int = NULL, @EffectiveDate datetime = '2012-01-11'
SELECT  AssetPrice.AssetId, AssetPrice.Price, AssetPrice.EffectiveDate
FROM    AssetPrice
JOIN    (
            SELECT  AssetId, MAX(EffectiveDate) EffectiveDate
            FROM    AssetPrice
            WHERE   EffectiveDate <= @EffectiveDate AND
                    (AssetId = @AssetId OR @AssetId IS NULL)
            GROUP BY AssetId
        ) Effective
        ON  AssetPrice.AssetId = Effective.AssetId AND
            AssetPrice.EffectiveDate = Effective.EffectiveDate
WHERE   (AssetPrice.AssetId = @AssetId OR @AssetId IS NULL)
于 2012-01-19T01:16:44.827 回答