【问题标题】:What works faster "longer table with less columns" or "shorter table with more columns"?什么工作得更快“列更少的更长的表”或“列更多的更短的表”?
【发布时间】:2013-02-20 01:09:52
【问题描述】:

我必须决定如何规划用于存储日期的表格。

我为每个用户设置了大约 20 个不同的日期,我猜现在有 100 000 个用户并且还在不断增长。

所以问题是对于 SELECT 查询,如果我制作包含 20 个字段的表,什么会更快?例如

“用户日期”

userId, date_registered, date_paid, date_started_working, ... date_reported, date_fired 20 个字段,表中有 100 000 条记录

或制作 2 张喜欢的桌子 第一个表“date_types”,上面列名有3个字段和20条记录。

   id, date_type_id, date_type_name

    1       5        date_reported
    2       3        date_registerd
    ...

第二个表有 3 个字段的实际记录

“用户日期”

userId, date_type, date
   201       2      2012-01-28
   202       5      2012-06-14
 ...

但随后有 2 000 000 条记录?

如果我需要添加更多日期,我认为第二个选项更通用现在担心表中有 200 万条记录的性能。

那么你认为哪个选项会更快?

【问题讨论】:

  • 不用担心速度。担心易于维护,让数据库为您做尽可能多的检查。

标签: mysql optimization database-performance


【解决方案1】:

较长的表将具有较大的索引。更宽的表会有更小的索引,但会占用更多的心理空间,并且可能会有更多的开销。您应该仔细检查您的架构以查看规范化是否完成。

但是,我会选择您的第二个选项。这是因为如果字段为空,您不一定需要存在这些字段。因此,如果用户没有被解雇,则无需为他们创建记录。

【讨论】:

  • 关于空字段的好点!大多数用户真的不会在第三个第五个状态之后继续前进。
  • 关于索引大小,我不认为您可以明确地说一种方法会产生比另一种方法更大的整体索引大小。如果您需要在每列上建立索引,或者需要有额外的多列索引来优化查找,那么具有 20 行的表可能具有比规范化表大得多的总体索引大小。更不用说您将在列表中列出 NULL 值列的一个日期索引记录(在规范化方法中根本不存在任何记录)。当然,我通常更关心查询延迟而不是索引大小。
【解决方案2】:

如果日期非常具体,并且用户将填写所有(或大部分)日期,那么我会使用宽表,因为实际编写查询以获取数据更容易。使用垂直表编写一个查询来询问所有用户在一个范围内的 date1 和 date2 在一个范围内要困难得多。

如果您知道需要动态创建日期类型的选项,我只会选择较长的表格。

【讨论】:

  • I would only go with the longer table if you know you need the option to create date types on the fly. 它的可能性不是必需的。我不同意第二个选项更难根据类型选择你所做的只是SELECT * FROM user_dates WHERE date_type = 2 或者如果你必须按名称使用类型,则离开加入 document_types 表。
  • 根据我的经验,在大多数不平凡的场景中查询确实变得更加困难。即使为每个用户获取 date_type 2 也需要在获取日期的每个场景中都必须执行此操作。
  • 我看不出它有什么不同,我仍然必须将此表加入 user_table 无论如何......但没关系,我实际上一直使用左连接。
【解决方案3】:

确定这一点的最佳方法是通过测试。一般来说,您所说的数据大小(20 个日期列乘 10 万条记录)对于 MySQL 表来说非常小,所以我可能只会使用一个包含多个列的表,除非您认为您将添加新类型的日期字段一直都希望有一个更灵活的模式。您只需要确保为查询中将用于过滤、排序、连接等的所有字段编制索引。

设计还可能会根据您想要对数据执行的查询类型来通知。例如,如果您希望您可能希望根据字段组合查询数据(即用户有某个特定日期,但没有另一个日期),那么在单个表上查询可能会更加优化,因为您可以使用简单的SELECT ... WHERE 查询。对于单独的表,您可能会发现自己需要执行子选择、奇数连接条件或 HAVING 子句来执行相同类型的查询。

【讨论】:

    【解决方案4】:

    只要在主表和 user_dates 表上索引了用户 ID 和日期类型 ID,我怀疑您在查询时会注意到一个问题。如果您要在任何一种情况下查询整个表,我'确信这需要相当长的时间(不过主要是发送数据)。在任何一种情况下,单个用户查找都将是即时的。

    不要为了一些可能的效率提高而牺牲关系;不值得。

    【讨论】:

    • 什么关系?我目前使用的第一个选项有 20 个字段,想知道是否要重建数据库,所以想知道我是否应该使用更通用的模型(第二个示例)。
    【解决方案5】:

    通常我会采用两种方式:将基本和最常用的属性放在一张表中。制作一个附加属性表,将 rarley used 属性放入其中,然后可以从应用层延迟获取。这样您就不会在每次获取用户时都进行 JOIN。

    【讨论】:

      猜你喜欢
      • 2015-08-22
      • 2022-11-24
      • 2015-09-05
      • 2020-11-27
      • 1970-01-01
      • 2021-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多