0

对于我目前的项目,我们想要展示统计数据并对其进行排名。就我而言,我正在谈论艺术家的“收藏”,计算艺术家曲目的播放次数,显示艺术家曲目已添加到播放列表中的播放列表的计数......这些都是非常特定于域的问题,但这是我的问题的一个具体例子。

主要问题是我将返回按顺序返回的所有这些统计属性的结果集。

这里有些例子:

  • 音乐登陆页面应显示最受喜爱的前 5 位艺术家。
  • 音乐登陆页面应显示播放次数最多的前 5 首曲目。

我的第一个想法是确定我需要一个计算聚合列。由于我想对这些值进行排序,这意味着对于我想要排序的每个聚合,一个 CLUSTERED INDEX 将是最佳的。其次,由于 CLUSTERED INDEX 列上的 DML 在插入时不连续时可能代价高昂,因此我需要将此作为计划作业。

所以,对于艺术家最喜欢的统计数据,这是我想出的 DDL。注意到我的 T-SQL 可能非常糟糕,但我认为意图很明确。

CREATE TABLE Stats_ArtistFavourites (
    FavouriteCount INT DEFAULT 0,
    ArtistId INT PRIMARY KEY NONCLUSTERED,
    FOREIGN KEY (ArtistId) REFERENCES Artists
)

CREATED CLUSTERED INDEX IDX_Favourites 
ON Stats_ArtistFavourites (FavouriteCount, ArtistId) DESC

如您所见,我需要为我想要跟踪的每个统计信息创建一个单独的表,否则我将不得不对不在 CLUSTERED INDEX 中的列进行排序。这看起来很丑陋的事实让我觉得我做错了。

我是否应该开始考虑集成 OLAP(我对 OLAP 多维数据集的经验很少)?或者也许是 Lucene?

4

3 回答 3

2

通过普通索引进行扫描类似于连接,因为普通索引包含一个索引值以及对每个叶子中的表块的引用。要提取非索引值,您需要通过此块引用“加入”表。

相反,聚集索引包含每个叶子的表数据本身,您可以在扫描时获得非索引字段值。

只要选择前 5 条记录,就可以使用普通索引,因为一张表总是更易于管理。

它会比集群索引慢一点,因为这意味着上面描述的“连接”,但它只有 5 条记录,你几乎不会注意到任何区别。

您甚至可以这样创建统计表:

CREATE TABLE stats (type INTEGER, score INTEGER, artist INTEGER);
CREATE INDEX ix_stats (type, score);

,这将帮助您更轻松地添加新的聚合值。

1因为type这里可以表示艺术家有多少次,他有多少次played等等。当您需要新的聚合时,您只需在表中创建一个新类型和 5 个新行,而不是更改其定义。2favoritedINSERT

同样,如果我理解您的任务,我们正在讨论从该表中选择数十条记录。在这种情况下,可管理性比选择前 5 名艺术家快 10 毫秒更重要。

于 2009-02-06T22:23:48.383 回答
0

您是否考虑过使用 RANK?您可能会对性能感到惊讶。

于 2009-02-08T03:21:57.763 回答
0

您可能会探索索引视图。 http://technet.microsoft.com/en-us/library/cc917715.aspx

  • 聚合可以预先计算并存储在索引中,以最大限度地减少查询执行期间的昂贵计算。
  • 可以预先加入表并存储结果数据集。
  • 可以存储连接或聚合的组合。

第一点看起来像你所追求的。

于 2009-02-06T22:25:46.817 回答