在它变得丑陋之前,我可以在 Sql server 表中存储多少条记录?

Posted

技术标签:

【中文标题】在它变得丑陋之前,我可以在 Sql server 表中存储多少条记录?【英文标题】:How many records can i store in a Sql server table before it's getting ugly? 【发布时间】:2010-05-07 11:54:42 【问题描述】:

我被要求为一个新系统做一些性能测试。 它只与少数客户一起运行,但随着他们的预期增长,这些是我在测试中使用的数字:

200 个客户,4 年的数据,每 5 分钟的数据变化。因此,每个客户每 5 分钟就有 1 条记录。 这意味着每个客户每年 365*24*12 = 105.000 条记录,这意味着我的测试有 8000 万条记录。 它有一个指向另一个表的 FK、一个 PK(唯一标识符)和一个关于 clientID 的索引。

这是 SqlServer 之所以会笑的原因,是因为它不会吓到他吗?对于一台四核 8 GB 机器来说,这是否太过分了,这是在边缘,还是.....

有人对这类数字有任何经验吗?

【问题讨论】:

将唯一标识符作为 PK 丢弃 - 改用 INT IDENTITY(至少对于您的集群键),并且您的表中有几亿行应该不会有任何问题... 我希望我们能做到这一点。代码中有一个基本类型,其中每个 id 都是一个 guid。因此,对于所有 FK 和实体框架重构的非常不可用的附加组件,这将需要很长时间。 【参考方案1】:

字段 PK 应该尽可能小,而不是随机的 - GUID 在这里很烂。主要问题是:

在所有外键中都使用 PK 来引用行,因此大 PK 使用更多空间?= 更多 IO。 随机 PK 意味着插入发生在各处 = 很多页面拆分 = 索引使用效率低下。

这有多糟糕?我知道在某些情况下你会失去 80% 的速度。

否则 - 没问题。我有一个超过 8 亿行的表,而且那里的东西非常快;)当然,您需要有体面的查询、体面的索引,而且显然它不能在单个 5400 RPM 绿色硬盘上运行以提高效率 - 但要适当IO 而不是愚蠢的查询和一些不错的索引,SQL 不会在几十亿行上犹豫不决。

所以,虽然“视情况而定”,但一般的答案是大表不是问题...... ...除非您进行 MASS 删除。删除一半的表将是一个巨大的事务,这就是为什么分区对于会计之类的东西很好 - 每年一个分区表意味着我可以在没有 DELETE 语句的情况下摆脱一年的数据;)

【讨论】:

+1 建议不要使用 Uniqueidentifier 作为 PK - 实际上,它不应该用作集群索引 - 这是关键。 我总是使用 bigint,uniqueidentifier 似乎不太好,但为什么它作为聚集索引不好(PK 总是聚集索引吗?) @Michel,你为什么总是使用 bigint?一个普通的 int 会做 20 亿次。有那么大的桌子吗???正确调整列的大小,bigint 将使索引与 int 相比翻倍,而 bigint 会浪费缓存内存并在页面上容纳更少的项目。每个索引都会拉入 PK,因此一个大 PK 会重复多次。 @Michel 说but why exactly is it bad as a clustered index (is a PK always a clustered index?) 聚集索引定义了表的实际物理顺序,就像纸质电话簿一样,聚集索引是姓氏+名字+中间名首字母。不,PK 并不总是聚集的,但如果您有一个本质上是顺序的代理键,那么它是聚集索引的不错选择。 ...更多... ...更多... 如果插入您的数据并且您的聚集索引是唯一标识符(基本上是随机的),它不会在表的末尾插入新行,就像它会一个身份。根据聚集索引(物理位置)的性质,您需要在现有行之间挤压新行。有时有足够的填充空间来执行此操作,有时您需要推送多行。【参考方案2】:

软件可以处理,你的服务器可以吗?嗯,这取决于

您只是存档吗?当然得到一千亿行,它不在乎,性能问题进来然后你查询数据。它越大,就总存储空间和对该数据的操作(删除、回滚段等)而言,您需要的空间就越大,最好是在内存中,但如果不是,则在快速的 tempdb 驱动器上。

对于 SQL 服务器而言,比处理大型数据集的处理器更重要的是内存和空间(尽管处理器肯定会影响它所花费的时间,而不是它可以处理的查询/数据的阈值)是内存和空间(两者都是HD 和 RAM,因为它会溢出到 TempDB 进行大型操作),这是在 容量 方面说话。为了性能,您需要磁盘 IO、内存和处理器能力。

如果您有足够的空间,它可以处理它的简短答案。它是否足够快处理它?这取决于您正在运行的查询类型以及性能的重要性。

最后一件事,don't forget to take a look at other questions here on optimizing large tables。

【讨论】:

【参考方案3】:

SQL Server 可以轻松存储这么多记录。

如果您正确设计了索引,并且正确规范了数据库,那么访问任意数量的记录绝对没有问题。通常,当他们的数据库中没有信息时,人们会在早期做出糟糕的设计决策,而你永远不会知道它,因为everything is fast for small "n"。

因此,虽然我会说 SQL Server 可以处理您正在做的事情,但我也想说现在是坐下来看看您的查询执行情况的好时机使用 SQL Server Profiler。一切仍然很快吗?您是否在频繁查询中看到过度扫描或散列导致性能下降?如果是这样,现在是分析和解决这些问题的时候了。


顺便说一句,人们真的很喜欢根据行数和列数来考虑大小限制。尝试进一步讨论字节,因为最终,字节是在报告查询中扫描的内容,而字节是存储到磁盘的内容。

【讨论】:

【参考方案4】:

真的太多了。我负责一个拥有 200 万注册用户的网站。

我们的一些表有超过 1 亿条记录,我们可以通过每天 400 万次的页面浏览量来实现出色的性能,但我必须承认,具有良好架构的缓存是事情不会变得丑陋的主要原因。

【讨论】:

【参考方案5】:

如果您追求极致的高性能,我会将 PK 设计为不是唯一标识符。如果您需要合并数据集,我会使用 INT IDENTITY + SMALLINT(甚至是 tinyint)来确定原始位置。您对您的设计没有多说,但尝试将 uniqueidentifier 用作聚集索引时存在问题。

只要有合适的服务器硬件,大多数体面的设计就可以了。不要计划在服务器上运行除操作系统和 SQL Server 之外的任何东西。主要关注的是 RAM,为了获得最佳性能,您需要为整个数据库、索引等提供足够的 RAM,而这超出了操作系统的使用范围。我什至看到大型服务器帮助糟糕的设计运行得非常好。

【讨论】:

+1 建议 NOT 使用 Uniqueidentifier 作为 PK - 实际上,它不应该用作 clustering index - 这是关键。跨度> 【参考方案6】:

SQL Server 可以处理 TB 级的数据。关键是您的设计正确并拥有正确的设备组合。例如,您可能需要分区。您确实需要考虑每个查询的每一毫秒的性能,并避免性能不佳的设计和查询技术,如 EAV 表和相关子查询和游标以及“像 '%sometext%'”。

如果您希望您的数据库有那么大,那么在开始设计之前购买并阅读封面以涵盖有关性能调整的书籍。糟糕的设计会扼杀数据库性能,一旦拥有 80,000,000 条记录,就很难纠正。

我还建议您找一位具有高性能、大容量数据库经验的 dba。这是一个全新的游戏设计,需要从一开始就考虑清楚。

在系统有这么多记录之前进行这种测试对您有好处。

【讨论】:

【参考方案7】:

即使是 MS Access 也可以嘲笑 50 万行表(取决于行大小)。

如果您没有任何要分析的查询,请将表视为一个文件。与sp_spaceused 相比,这些行并不是重要的数字。

如果您确实有一些查询,请将表视为一种数据结构。如何以最少的 IO 完成查询。使用查询计划,SET STATISTICS IO ON

【讨论】:

完全不同意,Access 无法处理 1,000 条记录而不会出现损坏和可靠性问题。 @AaronKempf ***.com/questions/1221435/…

以上是关于在它变得丑陋之前,我可以在 Sql server 表中存储多少条记录?的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server数据库更新语句突然变得很慢

LibreOffice 工具栏和 UI 元素在升级到 5.1 后变得丑陋

在 IE 中旋转文本,不会变得丑陋

从上面的值填充列值,直到它在SQL Server中达到新值

在 Java 中处理丑陋的 SQL

SQL Server存储过程中使用表值作为输入参数示例