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

Posted

技术标签:

【中文标题】如果表中的列太多,是不是会降低性能?【英文标题】:Is there a performance decrease if there are too many columns in a table?如果表中的列太多,是否会降低性能? 【发布时间】:2011-03-29 08:10:19 【问题描述】:

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

【问题讨论】:

【参考方案1】:

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

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

我的意见是,如果您的表现目前可以接受,除非您需要,否则不要寻求重新发明解决方案。

【讨论】:

每个人都有权有自己的意见。因为一个人的观点而贬低他,这在每本书中都可以找到,这似乎是不合理的。我在许多系统上工作过,每个系统都有超过 30 列的表格,但气味仍然存在。仅仅因为它在那里并且在生产中并不能使它正确。 对,我正在开发一个由 oracle 开发的 ERP,在他们最常用的表中有 50 多个列。【参考方案2】:

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

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

是否有一些列是您需要的频率低于其他列(换句话说,必需信息和经常使用的信息与可能只出现在一个地方而不是其他任何地方的其他内容之间是否存在自然划分),然后考虑拆分桌子。

如果您的某些列是 phone1、phone2、phone3 - 那么您有多少列并不重要,您需要一个具有一对多关系的相关表。

一般来说,虽然 30 列不是特别大,但应该还可以。

【讨论】:

【参考方案3】:

如果您真的需要所有这些列(也就是说,这不仅仅是表明您的表格设计不佳),那么请务必保留它们。

这不是性能问题,只要你

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

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

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

【讨论】:

我看到一个我认为合理的原因:在表中加载遗留或专有(索引或 csv)文件以利用数据库功能来利用它时。 @snowflake:事情就是这样发生的,但是不良代码气味仍然存在,应该检查数据/架构是否有潜在的重构。 除了主观意见外,我不明白“难闻的气味”或“设计不佳”是什么意思....请解释一下 这些术语确实有一些主观性。 “难闻的气味”是指您的应用程序可能设计不佳的某些代码中的迹象。这并不一定意味着它是,但其他阅读您的代码的人可能会得出这个结论。设计不佳意味着没有以合理或有效的方式编码某些东西,使用不适合使用的工具等。在这种情况下,它可能表明您需要重新考虑如何规范数据库设计。【参考方案4】:

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

【讨论】:

【参考方案5】:

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

【讨论】:

【参考方案6】:

30 对我来说似乎不算太多。除了必要的索引和正确的 SELECT 查询之外,对于宽表,2 个基本技巧非常适用:

    可以定义您的列as small as。 当每个表有大量列时,尽可能避免使用dynamic columns,例如VARCHAR 或TEXT。尝试使用固定长度的列,例如 CHAR。这是为了以磁盘存储换取性能。

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

    名称 - CHAR(70) 性别 - TINYINT(1) 年龄 - TINYINT(2) 生物 - 文字

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

不言而喻,这会引入大量的行,从而浪费大量磁盘存储,但如果您想要性能,我想这就是成本。

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

【讨论】:

【参考方案7】:

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

000 列,另一方面... How would you implement a very wide "table"?

【讨论】:

【参考方案8】:

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

As it is shown in here,归一化有八种形式。但是对于许多系统来说,应用第一、第二和第三范式就足够了。

因此,与其选择相关的列并编写长的 sql 查询,一个好的规范化数据库表会更好。

【讨论】:

我很久以前就读过这样的文档,并且我知道它们......但正如我所说,最常用的规范化形式是前三个。其余的不常用。我的建议是展示一些关于标准化的一般信息。是的,它讲述了 8,但是真的很难找到关于第 5 范式和 BCNF 和 DKNF 之外的规范化的信息。但你是对的(: @mp0int - 如果你编辑你的答案,我可以删除反对票 - 它目前已锁定。【参考方案9】:

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

【讨论】:

以上是关于如果表中的列太多,是不是会降低性能?的主要内容,如果未能解决你的问题,请参考以下文章

Mysql schema设计中的缺陷

excel表中表头固定,窗口冻结,但是列太多,表不能左右拉动了~~怎样才能使表头不懂,又能左右拉动呢?

高性能索引-高性能索引策略

如何以最佳性能明智地将右表中的列加入左列表

如果 Oracle OBIEE 中的列为空,则隐藏数据透视表中的列

防止 sqlplus 截断列名,没有单独的列格式