2012-01-19 30 views
2

對於給定的時間點,資產具有有效的價格。一些資產每週有一次新價格,一天一次。最近的價格是「有效價格」。如何調整臨時SQL Server表的性能

存儲所描述的關係的時態表看起來是這樣的:

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需要重新計算有效價格。我相信我無法創建索引視圖,因爲在索引視圖中不允許使用相關的聚合函數。

如何調整表格以非常快地檢索有效價格(最新價格)?

+0

哪個查詢需要「非常少量的時間」來計算價格? – 2012-01-19 01:27:28

+0

@ypercube查詢找到一個'AssetId'的有效價格是幾個計算中的瓶頸 - 它需要一個子查詢,非常像Rubens Farias在他的答案中寫的那個子查詢。 – Mike 2012-01-19 16:27:34

回答

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) 
+0

請注意,使用'startdate和enddate'之間的查詢具有非常糟糕的基數估計,因爲sql server不知道某個鍵不應該有重疊。 – 2015-04-10 21:20:37