假设一个表存储有关某个事件的粒度数据。它包含事件的日期、大约 30K 类型的类型维度和大约 100 个类别的类别维度,以及一些数字事实。
平均每天有 1500 万笔交易。每年超过 50 亿,每十年超过 60G。这不是大数据,但它很多。
SQL Server 2012 表可以容纳多少行?
当然,较旧的数据使用频率较低,并且可以在同一 DB 上的多个表中进行分区。但是这种分区应该什么时候开始发生呢?一年1桌?5年?
从评论中收集的其他信息:
考虑一下:我有足够的存储空间来保存该事件的 300 亿条记录。如果每个事件记录需要 1KB,我在那个表中有 30TB,并且有足够的存储空间(以及它的日志)。它的PK是bigint。
您如何看待一张包含历史数据的表格和另一张包含最新数据的表格?该表没有事务事件,而是有一个目录,例如客户端。每天将 OLTP 的目录复制到 DW 中。所以我有一个保存历史数据的表和另一个包含最新记录的表。
在我使用的设计中,ETL 提供历史表,然后我使用 row_number() 通过其 NK 获取每个实体的最新记录。运行起来非常昂贵,但这样我就可以保留过去存在的实体,并且不再在 OLTP 上。
如 SQL Server 的最大容量规范(SQL Server 2012)的 MSDN 页面所述:
“每个表的行数 = 受限于可用存储”(32 位和 64 位平台相同)
这一切都取决于系统的需求。仅仅基于性能问题,没有任何内在的需要进行分区。分区的主要目的是作为一种更轻松地管理将大量数据尽快输入或输出表并尽可能减少争用的方法。如果纯粹是为了提高查询性能,也许开始测试大约 10 亿行,但即便如此,如果你有一个好的数据模型和好的索引,你可能甚至不需要为此烦恼。此外,对于人们选择实现表分区的许多情况(如果他们的意图纯粹是与性能相关),过滤索引甚至过滤统计信息可能会做得很好。
但是,如果您需要快速删除一大块行,也许是为了使旧数据老化,那么表分区将有助于您
SWITCH
将“旧”数据移出。在这个级别上,这不是行的问题,而是您想要管理多少时间的问题。如果您想每月切换数据,则每月进行分区。如果您想每年老化数据,请尝试每年分区。更新
不知道为什么我之前没有提到这一点,但你应该看看 Partitioned Views。那就是当您有多个具有相同模式的表和一个在它们之间执行 UNION ALL 的视图时,并且每个表在该表中都有
CHECK CONSTRAINT
一个特定范围的数据(因此查询优化器知道从哪里获取数据)。通过这样做,您可以拥有两个表——当前表和历史表——然后查询命中其中一个或另一个(如果提前知道时间范围,例如仅命中最近 90天),或者如果数据可以在其中任何一个中,则使用视图。请参阅以下内容了解更多信息:我相信您甚至可以进行组合,其中“当前”表已分区(以便您可以快速切换传入的数据并切换出正在变“旧”的数据)、历史的非分区表和分区视图加入他们两个。然后您只需要一种方法将数据从新切换的分区中获取到“历史”表中。
此外,关于性能,还提供其他功能,具体取决于您使用的版本(有些仅随企业版提供)。但是你应该研究一下 ColumnStore Indexes、Data Compression,也许还有其他一些东西。