我开发了将大量数据存储在其数据库表之一(SQL Server版本8、9或10)中的软件。假设每天大约有100,000条记录插入到该表中。每年大约有3600万条记录。为了避免性能下降,我决定每天创建一个新表(名称中带有当前日期的表)以减少每个表的记录数。
你能告诉我,这是个好主意吗?SQL Server表是否有记录限制?还是您知道在性能大幅降低之前,一个表中可以存储多少条记录(或多或少)?
我开发了将大量数据存储在其数据库表之一(SQL Server版本8、9或10)中的软件。假设每天大约有100,000条记录插入到该表中。每年大约有3600万条记录。为了避免性能下降,我决定每天创建一个新表(名称中带有当前日期的表)以减少每个表的记录数。
你能告诉我,这是个好主意吗?SQL Server表是否有记录限制?还是您知道在性能大幅降低之前,一个表中可以存储多少条记录(或多或少)?
Answers:
对此很难给出一个通用的答案。它实际上取决于许多因素:
等等
就像在这里其他地方回答的那样,每天10万张,因此每张桌子是过大的-我建议每月或每周甚至每季度一次。您拥有的表越多,维护/查询的噩梦就越大。
这些是SQL Server 2008 R2的一些最大容量规格
bigint
)
我在SQL Server 2008 R2中有一个三列表,其中有60亿行以上。
我们每天都在查询它,以为我们的客户创建每分钟的系统分析图表。我还没有注意到任何数据库性能方面的问题(尽管它每天增长〜1 GB的事实确实使管理备份比我想要的要复杂得多)。
2016年7月更新
在备份变得足够大以至于我们决定截断两年以上的记录(大约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月更新
如果您打算将大量数据存储在单个表中,请不要。我强烈建议您考虑对表进行分区(手动或内置功能(如果您正在运行企业版)。这使得丢弃旧数据就像每周(每月/每月/一次)一次删除表一样容易。如果您没有Enterprise(我们没有),则只需编写一个脚本,该脚本每月运行一次,删除2年以上的表,创建下个月的表,并重新生成连接所有分区的动态视图。表格一起查询。显然,您应该根据用例的合理性来定义“每月一次”和“大于2年”。
您可以填充表,直到您有足够的磁盘空间。为了获得更好的性能,您可以尝试迁移到SQL Server 2005,然后对表进行分区,然后将各个部分放在不同的磁盘上(如果您具有可以真正帮助您的RAID配置)。仅在企业版SQL Server 2005中才可以进行分区。您可以在以下链接中查看分区示例:http : //technet.microsoft.com/zh-cn/magazine/cc162478.aspx
您也可以尝试为最常用的数据部分创建视图,这也是解决方案之一。
希望这可以帮助...
我在Windows2003的SQL Server 8上遇到的最大表是7.99亿,有5列。但是,要根据SLA和使用情况来衡量它是否良好,例如,加载50-100,000,000条记录,并查看它是否仍然有效。
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