关于mysql:如果表中的列过多,性能是否会下降?

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

除了增加数据总量之外,在表中具有大量列是否会带来性能损失? 如果是这样,将表格拆分成几个较小的表格会有所帮助吗?


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

只要您,这不是性能问题

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

如果您有30列甚至200列,那么数据库就没问题了。如果要一次检索所有这些列,只会使它工作起来有点困难。

但是有很多列是一种不好的代码味道。我不认为有任何合理的理由,一个设计良好的表将具有如此多的列,您可能需要与其他一些简单得多的表建立一对多的关系。


我不同意所有这些帖子所说的30列气味很糟糕的代码。如果您从未使用过具有30个以上合法属性的实体的系统,那么您可能没有太多经验。

HLGEM提供的答案实际上是最好的答案之一。我特别喜欢他的问题"是否存在自然分裂......经常使用还是不经常使用"是一个很好的问题,可以问问自己,您也许可以自然地分解桌子(如果情况变好了)失控)。

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


即使您已经选择了答案,我也要权衡一下。是的,表太宽会导致性能问题(以及数据问题),应将它们分离为具有一对一关系的表。这是由于数据库存储数据的方式(至少在SQL Server中不确定mySQl,但是值得在datbase如何存储和访问数据的文档中做一些阅读)。

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

是您需要的某些列是否比其他列少用(换句话说,所需信息和经常使用的信息以及可能仅出现在一个地方而不是其他地方的其他事物之间存在自然的划分),然后考虑拆分表。

如果您的某些列是诸如phone1,phone2,phone3之类的东西,那么您有多少列就不需要具有一对多关系的相关表。

通常,尽管30列不是特别大,但可能还可以。


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


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


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

  • 定义尽可能小的列。
  • 当每个表中有大量列时,请避免使用诸如VARCHAR或TEXT之类的动态列。尝试使用固定长度的列,例如CHAR。这是在磁盘存储性能之间进行权衡。
  • 例如,对于"人物"表中的"名称","性别","年龄","生物"列,最多包含100列甚至更多列,为了使性能最大化,最好将它们定义为:

  • 名称-CHAR(70)
  • 性别-TINYINT(1)
  • 年龄-TINYINT(2)
  • 生物-??TEXT
  • 这个想法是要定义尽可能小的列,并在合理可能的范围内以固定的长度定义列。动态列应位于表结构的末尾,因此固定长度的列在它们前面。

    不言而喻,这将导致大量磁盘存储浪费大量行,但是如果您想要性能,我想这就是代价。

    另一个技巧是,随着使用过程的不断发展,您会发现使用(选择或更新)的列要比其他列多得多,您应该将它们分成另一个表,以与包含不经常使用的列的另一个表形成一对一的关系,并且使用更少的列来执行查询。


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

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


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

    如此处所示,归一化有八种形式。但是对于许多系统而言,应用第一,第二和第三范式就足够了。

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


    明智的用法是,在某些情况下比较合适,例如,表服务于多个共享某些列但不共享其他列的应用程序,并且报表需要实时的单个数据池进行所有数据传输,而没有数据转换。如果一个200列的表格启用了这种分析能力和灵活性,那么我会说"很久了"。当然,在大多数情况下,标准化可以提供效率和最佳实践,但可以满足您的需要。