4

假设您有一个具有类型 2 渐变维度的表。

让我们用以下列来表示这个表:

* [Key]
* [Value1]
* ...
* [ValueN]
* [StartDate]
* [ExpiryDate]

在此示例中,假设 [StartDate] 实际上是系统知道给定 [Key] 的值的日期。所以我们的主键将由 [StartDate] 和 [Key] 组成。

当给定 [Key] 的一组新值到达时,我们将 [ExpiryDate] 分配给一些预定义的高代理值,例如“12/31/9999”。然后,我们将该 [Key] 的现有“最近”记录设置为具有等于新值的 [StartDate] 的 [ExpiryDate]。基于联接的简单更新。


因此,如果我们总是想获取给定 [Key] 的最新记录,我们知道我们可以创建一个聚集索引:

* [ExpiryDate] ASC
* [Key] ASC

尽管键空间可能非常宽(例如,一百万个键),但我们可以通过最初按 [ExpiryDate] 对它们进行排序来最小化读取之间的页数。而且由于我们知道给定密钥的最新记录将始终具有 [ExpiryDate] '12/31/9999',因此我们可以利用它来发挥我们的优势。

但是...如果我们想在给定时间获取所有 [Key] 的时间点快照怎么办?从理论上讲,整个键空间并不是同时更新的。因此,对于给定的时间点,[StartDate] 和 [ExpiryDate] 之间的窗口是可变的,因此按 [StartDate] 或 [ExpiryDate] 排序永远不会产生您要查找的所有记录的结果连续的。当然,您可以立即丢弃 [StartDate] 大于您定义的时间点的所有记录。


本质上,在典型的 RDBMS 中,哪种索引策略提供了最小化读取次数以检索给定时间点的所有键值的最佳方法?我意识到我至少可以通过 [Key] 对表进行分区来最大化 IO,但这当然不是理想的。

或者,是否有不同类型的缓慢变化维度以更高效的方式解决此问题?

4

2 回答 2

1

懒惰的 DBA

您是在谈论带回维度表中的所有值吗?如果是这样,那么为什么不添加一个具有额外覆盖范围的非聚集索引,以便您只从索引本身而不是从表中提取值呢?这样,您正在扫描带有一些附加“覆盖”值的 B 树,而不是可能执行表扫描?我不能保证相对性能,但是对于您显然正在处理的场景值得测试。

干杯

Ozziemedes http://ozziemedes.blogspot.com/

于 2010-01-09T05:07:02.093 回答
0

如果这确实是一个“缓慢变化的维度”表,我会考虑使用聚集列存储索引。我知道当你问这个问题时这不可用,但无论如何。你会在这里找到一些很棒的文档:“ https://msdn.microsoft.com/en-us/library/gg492088.aspx ”和这里“ http://www.nikoport.com/2013/07/05/clustered -columnstore-indexes-part-1-intro/ "。

现在,如果您想坚持使用行存储索引,如果您按顺序将数据插入表中,那么我过去所做的就是利用身份字段。您的查询将类似于:

    declare @id;
    select @id = min(ID) from table where date = '12/31/9999';
    select fields from table where key = 112 and id > @id; 
于 2016-10-26T15:33:08.250 回答