【发布时间】:2010-01-21 12:09:28
【问题描述】:
到目前为止,我对使用 C# windows 应用程序非常满意。我即将转向 Asp.net 开发网站。 要求使我在一个表中放置大约 50 列。我知道使用普通表格将其分成小表格的概念。
我尝试了谷歌搜索,但没有得到很多结果。 我需要知道具有 50 个属性的表是否会降低我的 Web 应用程序的性能?有人可以建议我吗?
【问题讨论】:
到目前为止,我对使用 C# windows 应用程序非常满意。我即将转向 Asp.net 开发网站。 要求使我在一个表中放置大约 50 列。我知道使用普通表格将其分成小表格的概念。
我尝试了谷歌搜索,但没有得到很多结果。 我需要知道具有 50 个属性的表是否会降低我的 Web 应用程序的性能?有人可以建议我吗?
【问题讨论】:
好吧,如果你把它们都带回来,你肯定会有网络成本(数据库和你的 .NET 代码之间的数据传输)和物化成本(在你的 DAL 中创建对象/DataTable 表示),那么你会肯定有一些成本。无论哪种方式,您都必须考虑数据库的页面大小。
但也许关键是:您需要所有数据吗?如果是这样,你能做的只有这么多。使用多个表并引入连接也会影响性能。
但在大多数情况下,尤其是 ASP.NET,最重要的数字如下:
因为您的应用服务器和客户端之间的带宽和延迟往往是关键。测量事物;确保您针对的是正确性能问题。
此外,ASP.NET 以不羞于存储比您期望的更多的东西(例如视图状态)而闻名;密切关注这一点,或者切换到更轻量级的模型,如 ASP.NET MVC。
【讨论】:
如果您谈论的是具有许多字段(或列)的数据库表,那么 50 并没有什么特别之处。
但是,您应该保持 DB 设计规范化,如果设计规范化为 50 个字段,则继续。
【讨论】:
一张表,50 列?
规范化的一点是避免插入、删除、更新异常
现在,它会像狗一样运行,有很多行,但在这里数据完整性胜过性能......
【讨论】:
与其考虑有多少列,建议你考虑一下列的数据类型。
去规范化也很流行。根据您的应用程序逻辑选择规范化。 (仔细考虑JOINS)
【讨论】:
这一切都归结为您将使用的查询类型。归根结底,它是您将从表中获取/写入表的数据量。如果您的大多数查询从/写入大多数列,是的,没有列会产生影响。
查询的周转时间与它读取/写入的数据量成正比。数据量越大,需要的时间就越长。大量列可能意味着大量数据(但并非总是如此)。
话虽如此,50 列并不是一个大数字。我遇到了超过 300 列的表格。但是,它也取决于您使用的 dbms。
【讨论】:
这取决于检索数据的内容和方式。当然 SELECT * 会告诉性能。您将需要根据需要选择必要的列并尝试使用 where 子句。这是从包含大量列和数据的表中执行的一种方法。
【讨论】:
"Do the simplest thing that could possibly work." (沃德·坎宁安)。
如果所有列都代表数据的单独元素,那么您遵循了良好的规范化规则,并且没有重复元素组,那么表中的列数实际上并不重要。如果你愿意,你可以开始担心行的大小与数据块的大小,你可能会或可能不会浪费多少空间等等,令人作呕,但根据我的经验,最好将你的数据放在一起在一个表中,除非有一些压倒性的功能原因为什么它应该分成多个表。不幸的是,我不得不使用数据库,其中有人预先假设单个表中的字段过多是一件坏事,因此他们将逻辑上的单个表分解为具有较少字段的多个表。在尝试进行更新时,这会成为一场噩梦。
祝你好运。
【讨论】:
根据您的实际意思,这可能是也可能不是问题。
如果 50 列的大小相对较小,并且每列都包含不同类型的数据(电话、城市、州、名字等),那么您可能没问题。
如果它们是电话 1、电话 2 等,您需要一个相关表,因为这很难维护和正确查询。例如,假设您现在有 50 个电话号码字段,而有一天您需要 51 个,那么您必须更改表结构和所有相关查询(您不是在生产中使用 select * 吗?)假设您想要要知道谁有电话号码 111-111-1111,您必须加入(或联合)表 50 次才能得到答案。这就是它可能会损害性能的地方。
第三种情况是 50 列各不相同,但由于字段的大小,它们一起将成为一条大记录。了解数据库将允许您创建一个大于记录可以包含的最大字节数的结构,它根本不会让您在记录中放置超过该字节数。此外,较长的记录往往会导致数据在磁盘上的存储方式出现问题,并可能导致检索速度变慢。在这种情况下,最好创建一个或多个与主表具有一对一关系的相关表。
【讨论】:
重要的不是表格的列数,而是表格的“宽度”。
例如,如果所有 50 列都是 bit 列,那么您将看到每行 7 个字节很小。
另一方面,如果所有 50 列都是 VARCHAR(4000) 列,那么您正在查看每行大约 200 MB 的潜在最大行大小(是的,SQL Server 会让您这样做),这显然会导致问题(实际上可能不会,但我的观点是数据的宽度很重要,而不是列数)。
唯一确定您是否会遇到问题的可靠方法是尝试并查看,但作为非常普遍的规则,它是尝试将行大小保持在 4KB(1 页)以下是个好主意,但这是一个非常普遍的规则:
VARCHAR 或 VARCHAR(MAX)),行大小可能会经常超过 4KB,这完全可以。这是一个复杂的主题——就像我说的,唯一可靠的方法就是尝试一下,看看它是否有效。
请注意,除了大对象(例如VARCHAR)之外,SQL Server 不允许您创建大于 1 页的行。
因为它增加了需要读取的数据量。
作为一个非常简单/人为的示例,假设您有一个按 ID 排序的表(即在 ID 上有一个聚集索引),并且您想要检索 ID 100 到 110 的记录。如果行大小很小(比如 200 字节),那么所有这些记录的总大小约为 2KB,远小于页面大小(4KB)。由于该表是按 ID 排序的,因此这些记录很可能都适合 1 页,最多 2 页,因此只需几次读取即可读取所有 10 条记录。
现在假设行大小更大(例如 2KB),那么所有这些记录的总大小现在是 20KB。所需的最小读取次数现在至少为 5,可能为 6。在繁忙的数据库服务器上,这些读取增加了额外的 I/O 和缓存中的额外内存压力。
根据存储的数据量,大对象和可变长度字段(例如VARCHAR)可能会将数据存储在单独的页面中,可以是 LOB 页面或行溢出页面。
这是什么意思?好吧,如果您有一个定义了许多此类列的表并且您执行SELECT * ... 查询,那么 SQL Server 需要检索所有这些额外的页面来读取所有这些额外的数据。我们最终会遇到与上述相同的情况 - 大量读取糟糕。
但是,如果我们只指定查询中的某些列,例如SELECT ID, Address ... 那么 SQL Server 就不需要费心读取包含我们不感兴趣的数据的页面了。尽管这个表可能定义了许多行宽很大的列,因为我们指定了我们感兴趣的列并且由于这些数据存储在单独的页面中,因此所需的读取次数仍然相对较低。
【讨论】: