如果表中的列太多,性能是否会降低?

Is there a performance decrease if there are too many columns in a table?

提问人:Richard Knop 提问时间:8/13/2010 最后编辑:divibisanRichard Knop 更新时间:7/21/2021 访问量:23834

问:

除了数据总量增加之外,表中包含大量列是否会产生性能成本?如果是这样,将桌子分成几个较小的桌子会有助于这种情况吗?

MySQL 数据库设计 架构

评论

0赞 Avatar 4/21/2023
相关且有帮助: stackoverflow.com/q/1473996/1066234

答:

9赞 tdammers 8/13/2010 #1

从技术上讲,30列绝对没问题。但是,具有许多列的表通常表明您的数据库未正确规范化,也就是说,它可能包含冗余和/或不一致的数据。

22赞 thomasrutter 8/13/2010 #2

如果你真的需要所有这些列(也就是说,这不仅仅是一个迹象,表明你的表设计得很差),那么一定要保留它们。

这不是性能问题,只要你

  • 对需要用于选择行的列使用适当的索引
  • 不要在 SELECT 操作中检索不需要的列

如果您有 30 列甚至 200 列,则对数据库没有问题。如果你想一次检索所有这些列,你只是让它工作得更困难一些。

但是有很多列是一种不好的代码气味;我想不出任何合理的理由,一个精心设计的表会有这么多列,而你可能需要与其他一些更简单的表建立一对多关系。

评论

1赞 snowflake 8/13/2010
我看到一个我认为合法的原因:在表中加载遗留或专有(索引或 csv)文件以利用数据库功能以利用它。
3赞 Donal Fellows 8/13/2010
@snowflake:这些事情就是这样发生的,但难闻的代码气味仍然存在,应该检查数据/模式是否有潜在的重构。
3赞 TOPKAT 6/17/2016
我不明白“难闻的气味”或“设计不佳”是什么意思,除了主观意见......请解释
1赞 thomasrutter 6/17/2016
这些术语确实存在一些主观性。“异味”是指某些代码中的标志,表明您的应用程序可能设计不佳。这并不一定意味着它是,但其他人阅读你的代码可能会得出这个结论。设计不佳意味着没有以合理或有效的方式编码某些东西,使用工具,而不是它们打算使用的方式,等等。在这种情况下,它可能表明您需要重新考虑如何规范化数据库设计。
5赞 Vincent Buck 8/13/2010 #3

应该没问题,除非你到处都是。始终只选择您需要的列。select * from yourHugeTable

2赞 Mp0int 8/13/2010 #4

除了性能之外,数据库规范化还需要具有太多表和关系的数据库。通过规范化,您可以轻松访问模型和灵活的关系,以执行不同的 sql 查询。

如图所示,有八种形式的归一化。但对于许多系统来说,应用第一、第二和第三范式就足够了。

因此,与其选择相关列和编写长 sql 查询,不如使用好的规范化数据库表。

评论

0赞 Mp0int 8/13/2010
我很久以前就读过这样的文档,我知道它们......但正如我所说,最常用的规范化形式是前三种。其余的不常用。我的 porpose 展示了一些关于规范化的一般信息。是的,它讲述了 8 个,但真的很难找到关于第 5 个正常形式以及 BCNF 和 DKNF 之外的归一化的信息。但你是对的(:
0赞 8/13/2010
@mp0int - 如果你编辑你的答案,我可以删除反对票 - 它目前被锁定了。
3赞 user359040 8/13/2010 #5

30 列通常不会被视为过多的数字。

另一方面,三列......您将如何实现一个非常宽的“表”?

29赞 HLGEM 8/13/2010 #6

即使你已经选择了答案,我也会对此进行权衡。是的,太宽的表可能会导致性能问题(以及数据问题),应将其分隔为具有一对一关系的表。这是由于数据库如何存储数据(至少在SQL Server中不确定MySQL,但值得阅读有关数据库如何存储和访问数据的文档)。

三十列可能太宽,也可能没有,这取决于列的宽度。如果将 30 列将占用的总字节数相加,它是否比记录中可以存储的最大字节数宽?

某些列是否比其他列更不经常需要(换句话说,在必需和经常使用的信息以及其他可能只出现在一个地方而不是其他地方的东西之间是否存在自然的分裂),然后考虑拆分表格。

如果你的某些列是 phone1、phone2、phone3 之类的东西,那么无论你有多少列,你都需要一个具有一对多关系的相关表。

一般来说,虽然 30 列不是特别大,而且可能没问题。

32赞 Wade 7/27/2011 #7

我不同意所有这些帖子,说 30 列闻起来像糟糕的代码。如果您从未在具有 30+ 合法属性的实体的系统上工作过,那么您可能没有太多经验。

HLGEM提供的答案实际上是最好的答案。我特别喜欢他的问题“是否存在自然分裂......经常使用与不经常使用“是问自己的非常好的问题,你也许可以以一种自然的方式打破桌子(如果事情失控)。

我的评论是,如果你的表现目前是可以接受的,除非你需要它,否则不要寻求重新发明一个解决方案。

评论

1赞 Nicktar 7/28/2011
每个人都有权有自己的意见。贬低某人,因为他有共同的观点,这在每本书中都可以找到,这似乎是没有道理的。我曾使用过许多系统,每个系统都有超过 30 列的表格,但气味仍然存在。仅仅因为它在那里并在生产中并不能使它正确。
1赞 Saqib 9/4/2019
是的,我正在开发一个由 oracle 开发的 ERP,在他们最常用的表中有 50+ 列。
6赞 datasn.io 10/19/2014 #8

30 对我来说似乎并不多。除了必要的索引和适当的 SELECT 查询之外,对于宽表,还有 2 个基本提示:

  1. 将列定义得尽可能小
  2. 当每个表有大量列时,请尽可能避免使用动态列,例如 VARCHAR 或 TEXT。请尝试使用固定长度的列,例如 CHAR。这是为了牺牲磁盘存储来换取性能。

例如,对于“person”表中具有多达 100 列甚至更多列的“name”、“gender”、“age”、“bio”列,为了最大限度地提高性能,最好将它们定义为:

  1. 名称 - 字符(70)
  2. 性别 - TINYINT(1)
  3. 年龄 - TINYINT(2)
  4. bio - 文本

这个想法是在合理可能的情况下以尽可能的长度定义列。动态列应位于表结构的末尾,因此固定长度的列都位于它们之前。

不言而喻,这将引入大量行浪费的大量磁盘存储,但正如您想要性能一样,我想这将是成本。

另一个提示是,随着您的进行,您会发现比其他列更频繁地使用(选择或更新),您应该将它们分隔到另一个表中,以形成与包含不常用列的另一个表的一对一关系,并使用较少的列执行查询。

3赞 BarryDevSF 8/14/2015 #9

在用法方面,它适用于某些情况,例如,表为多个应用程序提供服务,这些应用程序共享某些列但不共享其他列,并且报告需要为所有数据提供实时的单个数据池,而无需数据转换。如果一个 200 列表表能够实现这种分析能力和灵活性,那么我会说“做多”。当然,在大多数情况下,规范化可以提高效率,并且是最佳实践,但请根据您的需要做有效的事情。

评论

0赞 Avatar 4/21/2023
“例如,表为多个应用程序提供服务,这些应用程序共享某些列,但不共享其他列”。宾果游戏!当我搜索这个问题时,这正是我的情况。你指出这一点太好了。一个用户数据库由两个应用程序共享,然后是,将两个应用程序都需要的列添加到其中。否则,您最终会在两个单独的表中处理相同的列,这会变得混乱。