【问题标题】:Which has better performance?哪个性能更好?
【发布时间】:2010-12-27 14:13:42
【问题描述】:

我正在考虑在社交网络应用程序的上下文中用于 post 及其 cmets 的数据库模式,我正在徘徊这两者中哪一个会提供更好的性能:

我将帖子的 cmets 存储在 “评论” 表中,并将帖子存储在 “帖子” 表中。 现在我的 cmets 表架构如下所示:

postId commentId postedBy Date CommentBody

因为为了检索帖子的 cmets,我需要搜索所有 postId 与该特定帖子的 postId 匹配的帖子,甚至我的 postId 也无法成为主键,因为 postId 在列中是非唯一的(因为单个帖子的多个 cmets),因此 我在考虑是否可以将 postId 和 commentId 合并到一个单独的 commentId (这将成为主键) 使用哪个 postId 也可以检索 .这就是我的想法:

CommentId 将生成为 postId*100+i(其中 i 是帖子的第 i 个评论)

因此,为了检索帖子的 cmets(例如使用 postId=8452 ),我将搜索所有带有 commentId 的帖子(这将是主键),位于 845200 和 845299 之间......而不是使用 postId=8452 搜索所有 cmets ..(当然,这将 cmets 的最大数量限制为 100)。但这会带来任何性能提升吗?

【问题讨论】:

    标签: mysql database database-design rdbms


    【解决方案1】:

    这就是你要做的。以(例如)两倍于您预期的大小加载具有代表性数据的数据库。

    然后运行您的查询并针对两个版本的架构进行测试。

    然后,这是好事,每X 周使用新的最新数据重新测试一次,以确保情况没有改变。

    这就是成为 DBA 的全部意义所在。除非您的数据永远不会改变,否则数据库优化不是一劳永逸的操作。唯一可以确定的方法是在有代表性的条件下进行测试。

    其他一切都是猜测。有根据的猜测,不要误会我的意思,但我宁愿有一个确定性的答案,而不是任何人的猜测,尤其是因为前者会适应变化。

    我最喜欢的优化口头禅是“衡量,不要猜测!”

    【讨论】:

    • 在测试期间小心使用FLUSH,以确保缓存以您想要的方式影响您的测试。尤其要确保一个测试的缓存不会污染其他测试的结果。
    【解决方案2】:

    我会推荐:

    • 在 cmets 中使用带有复合键的两表结构,以获得最佳的索引唯一性。

    • 每篇文章 100 厘米是一个糟糕的限制,可能会打击你。

    • 对于视频/图片等,不要为 cmets 使用不同的表。

    • 如果 cmets 数量巨大,请添加评论存档表并移动旧 cmets 那里。大多数请求的 cmets(最新)将有一个更小更高效的表。

    • 将 blob(图片和视频)保存在不同的分区而不是数据库中。 Db 在文件级别会更小,碎片更少。

    问候, /t

    【讨论】:

    • 您能否告诉我,对于照片画廊、状态更新和配置文件更改等不同类别对象的 cmets,每个表都有哪些问题?
    【解决方案3】:

    如果您要获得大容量,您应该创建一个表格 Post 和一个表格 Comments,以便获得更小的表格 :)。并且不要忘记在它们上使用索引和分区。

    【讨论】:

    • 是的,我已经这样做了..即使我打算将 cmets 表分成某些部分,比如它们是来自照片或视频的评论还是定期状态更新,我计划为每个部分设置一个不同的表...听起来不错吗?
    【解决方案4】:

    使用复合键。或者,如果您使用的框架仅允许单列键,则 postId

    上的二级索引

    【讨论】:

      【解决方案5】:

      如果CommendId不是唯一的,你可以在(postId, CommentID)上创建一个复合PRIMARY KEY

      CREATE TABLE Comment
              (
              postId INT NOT NULL,
              commentId INT NOT NULL,
              …,
              PRIMARY KEY (postId, commentId)
              )
      

      如果您的表是MyISAM,您可以将commentId 标记为AUTO_INCREMENT,这将为每个帖子分配一个UNIQUE 递增值。

      如果是唯一的,可以在CommentId上创建PRIMARY KEY,在(PostId, CommentId)上创建二级索引:

      CREATE TABLE Comment
              (
              commentId INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
              postId INT NOT NULL,
              …,
              KEY (postId, commentId)
              )
      

      【讨论】:

        【解决方案6】:

        CommentId 将生成为 postId*100+i(其中 i 是帖子的第 i 个评论)

        因此,为了检索帖子的 cmets(例如使用 postId=8452 ),我将搜索所有带有 commentId 的帖子(这将是主键),位于 845200 和 845299 之间......而不是使用 postId=8452 搜索所有 cmets。 . (当然这将 cmets 的最大数量限制为 100)。但这会带来任何性能提升吗??

        这可能会提供比基于 postId 外键列的查询更差的性能,但唯一可以确定的方法是尝试这两种技术(如 paxdiablo 所建议的那样)并测量性能.

        【讨论】:

          猜你喜欢
          • 2010-11-16
          • 2013-03-12
          • 2011-10-06
          • 2011-04-04
          • 2019-05-06
          • 2011-06-12
          • 2014-12-19
          • 2015-03-14
          相关资源
          最近更新 更多