我开发的软件在其数据库表(SQL Server版本8,9或10)中存储了大量数据。假设每天大约有100,000条记录插入到该表中。这大约是每年3600万条记录。由于担心我会失去性能,我决定每天创建一个新表(名称中包含当前日期的表)以降低每个表的记录数。
你可以告诉我,这是不是一个好主意? SQL服务器表是否有记录限制?或者你知道在性能显着降低之前可以在表中存储多少条记录(或多或少)?答案 0 :(得分:83)
这些是Maximum Capacity Specifications for SQL Server 2008 R2
中的一部分答案 1 :(得分:36)
我有一个三列表,在SQL Server 2008 R2中只有超过60亿行。
我们每天都会查询它,为我们的客户创建逐分钟的系统分析图表。我没有注意到任何数据库性能命中(尽管事实上它每天增长大约1 GB确实使管理备份比我想要的更多)。
2016年7月更新
我们在备份变得足够大以便我们决定截断超过两年的记录(大约700 GB存储在多个备份中,包括昂贵的磁带上)之前,已经 ~245亿行。值得注意的是,在这个决定中,表现并不是一个重要的动力(即它仍然很有效)。
对于发现自己试图从SQL Server中删除200亿行的任何人,我强烈推荐this article。链接死亡时的相关代码(阅读文章以获得完整说明):
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月更新
如果您计划将这么多数据存储在一个表中:不要。我强烈建议您考虑表分区(如果您正在运行企业版,则需要手动或使用内置功能)。这使得丢弃旧数据就像截取表格一样简单(周/月/等)。如果您没有Enterprise(我们没有),您只需编写一个每月运行一次的脚本,删除超过2年的表,创建下个月的表,并重新生成一个连接所有分区的动态视图桌子在一起,便于查询。显然,“每月一次”和“超过2年”应由您根据对您的用例有意义的内容来定义。直接从包含数百亿行数据的表中删除将a)花费大量时间并且b)将事务日志填满数百或数千次。
答案 2 :(得分:32)
很难给出一个通用的答案。这实际上取决于多种因素:
等
正如其他地方所解释的那样,每桌10万次,因此每张桌子都是矫枉过正 - 我建议每月或每周甚至每季度一次。你拥有的表格越多,维护/查询的噩梦就越大。
答案 3 :(得分:19)
我不知道行限制,但我知道行数超过1.7亿。您可以使用分区表(2005+)或连接多个表的视图加快速度。
答案 4 :(得分:18)
我不是特别了解MSSQL,但3600万行对于企业数据库并不大 - 使用大型机数据库时,100,000行听起来像配置表: - 。)。
虽然我不是某些的微软软件的忠实粉丝,但这不是我们在这里谈论的Access:我认为他们可以使用他们的企业DBMS处理相当大的数据库大小。
我怀疑几天的分辨率可能过于精细,如果真的需要分开的话。
答案 5 :(得分:5)
我们在SQL Server 2005和2008中拥有超过10亿行的表(每天增加3000万行)。我无法想象每天都会把那个分成一张新桌子的老鼠窝放下来。
添加适当的磁盘空间(无论如何都需要)和RAM。
答案 6 :(得分:4)
这取决于,但我想说为了简单起见,最好将所有内容保存在一个表中。
每天100,000行并不是那么多。 (取决于您的服务器硬件)。我个人看到MSSQL在单个表中处理多达100M行没有任何问题。只要你保持你的索引顺序,它应该是好的。关键是要有堆的内存,以便不必将索引换成磁盘。
另一方面,它取决于您如何使用数据,如果您需要进行大量查询,并且需要跨越多天的不太可能的数据(因此您不需要加入表)将它分成多个表会更快。这通常用于工业过程控制等应用中,您可能每10秒钟读取50,000个仪器上的值。在这种情况下,速度非常重要,但简单性并非如此。
答案 7 :(得分:3)
我们在表上溢出了一次整数主键(大约24亿行)。如果有一个行限制,你不可能每年只有3600万行。
答案 8 :(得分:2)
您可以填充表,直到有足够的磁盘空间。 为了获得更好的性能,您可以尝试迁移到SQL Server 2005,然后对表进行分区并将部件放在不同的磁盘上(如果您有可以真正帮助您的RAID配置)。只能在企业版的SQL Server 2005中进行分区。您可以在此链接中查看分区示例: http://technet.microsoft.com/en-us/magazine/cc162478.aspx
此外,您可以尝试为最常用的数据部分创建视图,这也是解决方案之一。
希望这有助于......
答案 9 :(得分:0)
我在Windows2003上的SQL Server 8上遇到的最大表是7.99亿,有5列。但是,它是否善意是根据SLA和使用案例来衡量的 - 例如加载50-100,000,000条记录并查看它是否仍然有效。
答案 10 :(得分:-1)
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
答案 11 :(得分:-4)
每月对表进行一次分区。这是处理每日大量涌入的表的最佳方式,无论是oracle还是MSSQL。