【问题标题】:MySQL Performance: Single table or multiple tables for large datasetsMySQL 性能:大型数据集的单表或多表
【发布时间】:2013-12-21 09:50:06
【问题描述】:

我正在构建一个应用程序来支持超过 200,000 个注册用户,并希望为每个用户添加地址簿功能以导入他们自己的联系人(例如姓名、地址、电子邮件等)。每个用户将有大约 150 个不同的联系人,每条记录有 10-15 个字段。

我的问题很简单:考虑到用户数量和每个用户的联系人数量,是为每个用户的通讯录创建单独的表,还是为关联的用户帐户创建一个带有 user_id 查找的单个表更好?

如果您能从性能角度解释原因,将不胜感激。

更新:规格

针对 cme​​ts 中的问题,以下是规范:我将在 AWS RDS (http://aws.amazon.com/rds) 上托管数据库。这将主要是繁重的读取负载,而不是写入。当访问写入时,它将在 INSERT 和 UPDATE 之间取得平衡,几乎没有删除。想象一下您查看和编辑自己的通讯录的次数。

谢谢

【问题讨论】:

  • 拥有一张表要好得多,因为它更容易检索和维护。不过,您可以稍后对表进行分区。几百万条记录对于mysql来说并不多
  • 需要更多信息然后这个...什么 MySQL 版本?什么存储引擎?表描述会很好..它会是一个繁重的写入或繁重的读取应用程序还是两者兼而有之?以及基于 INSERTS、UPDATES 或 DELETES 的性能观点是什么??
  • 您需要问自己一个简单的问题:您使用的是机械硬盘还是固态硬盘?差异是巨大的。但是,对于一个简单的答案 - 一张桌子更容易管理。每个用户都有一个表也违反了许多(逻辑偶数)规则。它基本上是0意义。这就像在一场大型比赛前 5 分钟朝自己的脚开枪,然后询问这是否是一个好举动。
  • @RaymondNijland 谢谢,请查看更新的答案。
  • @N.B.它是 Amazon RDS,所以我认为不太相关?

标签: mysql sql performance database-performance


【解决方案1】:

响应规范的具体答案 一张联系人数据表,带有索引的外键列返回给用户。查找特定用户的联系人will require about 3 seeks,一个相对较小的数字。如果搜索遇到瓶颈,请使用 SSD。

如果您的 15 列每列有 100 个字节,并且您有 150 个字节,那么每个用户的最大数据传输量为 256k。我会将应用程序设计为仅显示预先需要的联系数据(比如前 3 个最有用的联系点——姓名、电子邮件、电话),然后在请求特定联系人时提取更多细节。在(可能)极少数情况下,如果您需要所有联系人的信息(例如导出到 CSV),请考虑 SELECT INTO OUTFILE(如果您有该访问权限)。 vCard 输出的性能会降低:您需要获取所有数据,然后填充正确的格式。如果您经常需要 vCard,请考虑在数据库更新时将 vCard 写入(缓存方法)。

如果仍未满足性能要求,请考虑partitioning on the user id

一般答案

围绕 KISS 和您的性能要求设计您的架构,同时记录可扩展性计划。

在这种特殊情况下,我认为数据量并不极端,因此我会将 KISS 倾向于一张桌子。但是,我不清楚您将要进行哪种查询——JOIN 是通常的性能消耗,而不是直接的 SELECT。我还不清楚您的 SELECT/UPDATE 组合。如果读取量大且由用户读取,则只需一个表即可。

无论如何,如果在实施后您发现性能要求没有得到满足,我建议您考虑通过更快的硬件、不同的引擎进行扩展(例如 MyISAM 与 InnoDB ——了解您的特定 MySQL 版本的不同之处!) 、物化视图或分区(例如,围绕相应用户名的第一个字母——假设你有一个)。

【讨论】:

  • 您真的应该阅读这篇文章“与 MyISAM 相比,InnoDB 在读/写测试中的吞吐量提高了 35 倍,在只读测试中的吞吐量提高了 5 倍,在 36 个 CPU 内核上具有 90% 的可扩展性。” ... oracle.com/partners/en/knowledge-zone/…blogs.oracle.com/MySQL/entry/…
  • “更快”是一个加载词。在您的情况下是否更快取决于您在做什么。参见例如this post on MySQL performance blog。 (而且我不认为 -1 是公平的,请阅读该帖子以了解利弊——我并不是说 MyISAM 通常更快:我警告说“我没有所有的事实”。)
  • InnoDB 在几个方面都远远优于 MyISAM 观看此vimeo.com/20990641
  • -1 表示答案不是一个好的答案。 MyISAM / InnoDB 在很多方面都不同,既然您正在阅读 percona 博客,那么我相信您对这些差异很熟悉。在当今时代,几乎没有理由使用 MyISAM,它迄今为止确实发挥了最大的作用。建议一个过时的引擎而不是一个非常非常好的引擎是一个糟糕的建议,有人可能会在谷歌上搜索你的答案并认为 MyISAM 确实更快或更好的选择。编辑:删除了反对票。
  • @RaymondNijland:我遇到了this situation,我使用MyISAM 来克服它。
【解决方案2】:

有一个单一的表,但按用户的起始字母分区表,如所有以 A 开头的姓氏,将被加载到 1 个分区中。所有以 B 开头的名称都将加载到另一个分区中。

您还可以进行一些分析以找到正确的分发密钥。

【讨论】:

    【解决方案3】:

    我不是 DBA,但我建议您适当地规范化数据库、添加索引等,不要为了解决可能不存在的性能问题而对其进行错误处理。如果可能,请让 DBA 检查您的架构。我认为 20,000 个用户并不过分。所有 200,000 名用户不太可能在处理一个人的输入所需的相同 x 毫秒内点击更新按钮。任何时候只有少数人会登录,他们中的大多数人会填写数据或盯着网页上的现有数据,而不是点击更新按钮。如果碰巧有一群人同时击中它,那么可能会出现性能等待而不是崩溃。这是您的架构的粗略布局(里程可能会有所不同):

    用户
    长用户 ID 主键
    字符串名
    字符串姓氏

    联系
    长 contactID 主键
    长用户 ID 外键
    字符串名
    字符串姓氏

    地址
    长地址ID主键
    长 contactID 外键

    【讨论】:

      猜你喜欢
      • 2010-11-13
      • 2012-04-24
      • 1970-01-01
      • 2013-09-18
      • 1970-01-01
      • 2012-08-24
      • 1970-01-01
      • 1970-01-01
      • 2011-09-12
      相关资源
      最近更新 更多