【发布时间】:2008-09-23 12:39:53
【问题描述】:
假设您有一个包含三列的大表,如下所示:
[id] INT NOT NULL,
[date] SMALLDATETIME NOT NULL,
[sales] FLOAT NULL
还假设您仅限于一个物理磁盘和一个文件组 (PRIMARY)。您希望此表能够保存 10,000,000+ ids 的销售额,跨越 100 个日期(很容易 1B+ 记录)。
与许多数据仓库方案一样,数据通常会按日期顺序增长(即,每次执行数据加载时,您都将插入新日期,并且可能会更新一些较新的数据日期)。出于分析目的,数据通常会被查询并聚合为随机的约 10,000 个 id 集合,这些 id 将通过与另一个表的连接来指定。通常,这些查询不指定日期范围,或指定非常宽的日期范围,这引出了我的问题:索引/分区此表的最佳方法是什么?
我已经考虑了一段时间,但遇到了相互矛盾的解决方案:
选项#1:由于数据将按日期顺序加载,因此将聚集索引(和主键)定义为 [date], [id]。还创建一个“滑动窗口”分区功能/日期方案,允许新数据快速移入/移出表。可能会在 id 上创建一个非聚集索引以帮助查询。
预期结果 #1: 这种设置对于数据加载来说会非常快,但在分析读取方面不是最理想的,因为在最坏的情况下(不受日期限制,不走运查询一组id),可以读取100%的数据页。
选项#2:由于一次只查询一小部分 id 的数据,因此将聚集索引(和主键)定义为 [id], [date]。不要费心创建分区表。
预期结果 #2: 加载数据时预期性能会受到巨大影响,因为我们无法再快速按日期限制。当涉及到我的分析查询时,预计会有巨大的性能优势,因为它将最小化读取的数据页数。
选项 #3: 集群(和主键)如下:[id]、[date];日期上的“滑动窗口”分区功能/方案。
预期结果#3:不确定会发生什么。鉴于聚集索引中的第一列是 [id],因此(我的理解)数据是按 ID 排列的,我希望我的分析查询有良好的性能。但是,数据是按日期分区的,这与聚集索引的定义相反(但仍然对齐,因为日期是索引的一部分)。我还没有找到很多关于这种情况的文档,以及我可以从中获得哪些性能优势(如果有的话),这让我想到了最后一个额外的问题:
如果我在一个磁盘上的一个文件组上创建一个表,在一列上有一个聚集索引,那么在同一列上定义一个分区是否有任何好处(除了加载数据时的分区切换)?
【问题讨论】:
标签: sql sql-server database