2010-11-22 24 views
9

我有一个场景,其中有大量关于项目的状态数据。 该项目的状态从分钟到分钟更新,在不久的将来约有50,000件物品。因此,在一个月内,将会有约22.23亿行数据。在获得旧数据之前,我必须在主表中保留至少3个月的时间。我必须计划根据特定项目(其ID)和数据范围(通常最多一个月范围)来实现快速查询 - 例如,从表中选择A,B,C其中ItemID = 3000和'2010-10-01'和'2010-10-31 23:59:59.999'之间的日期'在SQL Server 2008中为查询性能分区

所以我的问题是如何设计一个分区结构实现那个?

目前,我基于“项目的唯一标识符”(一个int)mod“分区数”进行分区,以便所有分区平均分配。但是它的缺点是在表上保留一列作为分区函数的分区列,因此将该行映射到其分区。所有这些都增加了一点额外的存储空间。另外,每个分区都映射到不同的文件组。

+1

这是一些负载。阅读[这里](http://sqlblog.com/blogs/paul_nielsen/archive/2007/12/12/10-lessons-from-35k-tps.aspx)关于大量写入(你有50k行*每秒*来电)。我很好奇你将如何解决这个问题:我没有这种数量/增长率的经验) – gbn 2010-11-22 18:58:38

+0

你想要设计写查询效率还是读查询效率?你有什么样的读取负载? – 2010-11-30 12:56:24

回答

10

对于查询性能,永远不会执行分区。随着分区的表现将总是更糟糕,最好的你可以希望是没有大的回归,但从来没有改善。

对于查询性能,分区可以做的任何事情和索引可以做得更好,这应该是你的答案:适当的索引。

分区对于IO路径控制情况(分布在归档/当前卷)或ETL负载中的快速切入转出场景非常有用。所以我会理解,如果你有一个滑动窗口和按日期分区,所以你可以快速切换出不再需要保留的数据。

分区的另一个小例子是最后一页插入锁存争用,如Resolving PAGELATCH Contention on Highly Concurrent INSERT Workloads中所述。

您的分区方案和用例似乎不适合任何应用场景(也许是最后一种场景,但从描述中不清楚),因此很可能会伤害性能。

0

我同意Remus的看法,按照你自己的结果显示,分区并不会改善事物。

忘记分区,索引ID和日期,并运行在有巨大内存的盒子上;有什么结果?

1

我不完全同意Remus Rusanu。我认为如果存在逻辑原因(与您的用例相关),分区可能会提高性能。我的猜测是你只能对itemID进行分区。另一种方法是使用日期,但是如果你不能预测日期范围不会跨越给定分区的边界(没有查询肯定会在一个月内),那么我会坚持itemId分区。

如果只需要计算一些项目,另一个选项是有一个覆盖索引:在主分化字段(itemId)上定义一个INDEX,它包含需要计算的字段。

CREATE INDEX idxTest ON itemId INCLUDE quantity; 
1

应用型划分实际上可以查询性能有益。在你的情况下,你有50K项目和2G行。例如,您可以创建500个表,每个表名为status_nnn,其中nnn介于001和500之间,并在这些表中“分区”您的项目状态,其中nnn是项目ID的函数。这样,给定一个项目ID,您可以将您的搜索优先限制为整个数据的0.2%(大约4M行)。

这种方法有很多缺点,因为您可能需要处理动态sql和其他不愉快的问题,尤其是如果您需要汇总不同表中的数据时。但是,它肯定会提高某些查询的性能,s.a.你提到的那些。

基本上可应用的分区类似于创建非常广泛和平坦的索引,针对非复制数据的特定查询进行了优化。

应用程序分区的另一个好处是,您可以在理论上(取决于您的用例)在不同的数据库甚至不同的服务器之间分配您的数据。再次,这很大程度上取决于您的具体要求,但我已经看到并使用了大量数据集(数十亿行),其中应用程序分区工作得很好。