SQL Server:表中的最大行数
我开发的软件可以在其中一个数据库表(SQL Server版本8,9或10)中存储大量数据。 比方说,每天大约有100,000条logging被插入到表格中。 这是每年约三千六百万logging。 为了避免性能上的损失,我决定每天创build一个新的表格(一个当前date的表格),以减less每个表格的logging数量。
你能告诉我,这是不是一个好主意? 是否有SQL服务器表的logging限制? 或者你知道在一个表格中可以存储多less个logging(或多或less)吗?
这很难给出一个通用的答案。 这取决于一些因素:
- 你的排是多大?
- 你存储什么样的数据(string,斑点,数字)
- 你如何处理你的数据(只要保存为档案,定期查询)
- 你的桌子上有索引 – 有多less
- 什么是你的服务器规格
等等
正如在这里的其他地方所回答的,每天10万,每张桌子都是过度的 – 我build议每月或每周,甚至每季度一次。 更多的表,你会有更大的维护/查询噩梦。
这些是SQL Server 2008 R2的最大容量规格
- 数据库大小:524272兆兆字节
- 每个SQL Server实例的数据库数:32,767
- 每个数据库文件组:32,767
- 每个数据库的文件数:32,767
- 文件大小(数据):16TB
- 文件大小(日志):2兆兆字节
- 每桌的行数: 受可用存储限制
- 每个数据库的表: 受限于数据库中的对象数
我有一个三列表,在SQL Server 2008 R2中只有超过60亿行。
我们每天都在查询它,为我们的客户创build分钟 – 分钟的系统分析图表。 我没有注意到任何数据库性能命中(尽pipe事实上,它每天增长〜1 GB的确使pipe理备份比我想要的多一点)。
2016年7月更新
在备份变得足够大以至于我们决定截断超过两年的logging之前(约700 GB存储在多个备份中,包括在昂贵的磁带上)之前,我们做了大约245亿行 。 值得注意的是,绩效在这个决定中并不是一个重要的激励因素(即它仍然很好)。
对于任何发现自己试图从SQL Server中删除200亿行的人,我强烈推荐这篇文章 。 链接消失时的相关代码(阅读文章以获得完整的解释):
ALTER DATABASE DeleteRecord SET RECOVERY SIMPLE; GO BEGIN TRY BEGIN TRANSACTION -- Bulk logged SELECT * INTO dbo.bigtable_intermediate FROM dbo.bigtable WHERE Id % 2 = 0; -- minimal logged because DDL-Operation TRUNCATE TABLE dbo.bigtable; -- Bulk logged because target table is exclusivly locked! SET IDENTITY_INSERT dbo.bigTable ON; INSERT INTO dbo.bigtable WITH (TABLOCK) (Id, c1, c2, c3) SELECT Id, c1, c2, c3 FROM dbo.bigtable_intermediate ORDER BY Id; SET IDENTITY_INSERT dbo.bigtable OFF; COMMIT END TRY BEGIN CATCH IF @@TRANCOUNT > 0 ROLLBACK END CATCH ALTER DATABASE DeleteRecord SET RECOVERY FULL; GO
2016年11月更新
如果你打算把这么多的数据存储在一张表中:不要。 我强烈build议您考虑表分区(手动或使用内置function,如果您正在运行企业版)。 这使得删除旧数据就像截断一个表(一周/每月等)一样简单。 如果您没有Enterprise(我们没有),那么您可以简单地编写一个脚本,每个月运行一次,删除大于2年的表,创build下个月的表,并重新生成一个dynamic视图,将所有分区表一起轻松查询。 显然,“一个月一次”和“两年以上”应该由您根据您的使用情况的意义来定义。 直接从一个具有数百亿行数据的表中删除将花费大量的时间和b)数百或数千次填满交易日志。
我不知道行限制,但我知道行数超过1.7亿行。 您可以使用分区表(2005+)或连接多个表的视图加快速度。
我并不了解MSSQL,但是对于企业数据库来说,3600万行并不是很大 – 对于大型机数据库来说,对于我来说,100,000行听起来像是一个configuration表。
虽然我不是微软某些软件的忠实拥趸,但这并不是我们在这里谈论的Access:我假设他们可以用他们的企业数据库pipe理系统处理相当大的数据库大小。
如果真的需要分割的话,我怀疑可能是分解它的日子太好了。
我们在SQL Server 2005和2008中有超过10亿行的表(每天增加3000万)。 我无法想象每天都会把老鼠分成一个新桌子。
添加适当的磁盘空间(无论如何您需要)和RAM更便宜。
这取决于,但我想说为了简单起见,把所有东西放在一张桌子里最好。
每天十万行不是那么多。 (根据您的服务器硬件)。 我亲眼看到MSSQL在单个表中处理高达100M行没有任何问题。 只要你保持你的指标,它应该是一切都好。 关键是要有大量的内存,以便索引不必交换到磁盘。
另一方面,这取决于你如何使用数据,如果你需要做大量的查询,并且需要跨越多天的不太可能的数据(所以你不需要join表),这将是更快地将其分成多个表格。 这通常用于诸如工业过程控制等应用中,您可能每10秒读取50,000个仪器的值。 在这种情况下,速度是非常重要的,但简单却不是。
我们在一个表上溢出了一个整数主键(约24亿行)。 如果有一个行限制,你不可能每年只有三千六百万行。
您可以填充表,直到有足够的磁盘空间。 为了获得更好的性能,您可以尝试迁移到SQL Server 2005,然后对表进行分区,然后将这些部分放在不同的磁盘上(如果您的RAIDconfiguration对您有帮助)。 分区只能在SQL Server 2005的企业版中使用。您可以在此链接中查看分区示例: http : //technet.microsoft.com/zh-cn/magazine/cc162478.aspx
你也可以尝试为最常用的数据部分创build视图,这也是解决scheme之一。
希望这有助于…
我在Windows2003的SQL Server 8上遇到的最大的表是799万5列。 但是否是好的呢,就是要根据SLA和使用情况进行衡量 – 例如,加载50-100,000,000条logging,看看它是否仍然有效。
SELECT Top 1 sysobjects.[name], max(sysindexes.[rows]) AS TableRows, CAST( CASE max(sysindexes.[rows]) WHEN 0 THEN -0 ELSE LOG10(max(sysindexes.[rows])) END AS NUMERIC(5,2)) AS L10_TableRows FROM sysindexes INNER JOIN sysobjects ON sysindexes.[id] = sysobjects.[id] WHERE sysobjects.xtype = 'U' GROUP BY sysobjects.[name] ORDER BY max(rows) DESC
每月对表进行分区。这是处理日常大量数据表的最佳方式,无论是oracle还是MSSQL。