假设您有一张桌子,桌子的类型2的变化缓慢。

让我们用以下几列来表示该表,如下所示:

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


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

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



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

* [ExpiryDate] ASC
* [Key] ASC


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

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



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

或者,是否存在另一种类型的缓慢变化的尺寸以更有效的方式解决了此问题?

最佳答案

懒惰的DBA

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

干杯

Ozziemedes
http://ozziemedes.blogspot.com/

10-02 05:47