【问题标题】:DB Table Optimization join vs repeat columns数据库表优化连接与重复列
【发布时间】:2010-09-27 17:58:27
【问题描述】:

这更像是一种偏好,但我想知道人们认为什么是执行的最佳选择。我有一个问题、答案和观点(因为我需要跟踪哪个用户提出了观点)

表转储

Question:
  id
  title

Answer:
  id
  question_id
  user_id
  response

Point_Answer:
  id
  answer_id
  user_id
  points

因此,在此布局中要获得最佳答案将需要复杂的连接序列。

SELECT t2.id, t2.user_id, t2.response, MAX(points)
FROM Question as t1,
  (SELECT qa.*, SUM(pa.points) as points
  FROM answer as qa, Point_Answer as pa
  WHERE qa.id = pa.answer_id
  GROUP BY qa.id) as t2
WHERE t1.id = %s AND t1.id = t2.question_id

如果我这样改的话:

Question:
  id
  title

Answer:
  id
  question_id
  user_id
  response
  points

Point_Answer:
  id
  answer_id
  user_id
  points

查询会减轻负担

SELECT A.id, A.user_id, A.response, MAX(points)
FROM Question as Q, Answer as A
WHERE Q.id = %s AND Q.id = A.question_id
GROUP BY A.id

还意味着我必须确保添加 Point_Answer 时添加 Answer.points。所以基本上是一个额外的更新。基本上是“完整性与冗余”和一些优化,更好的方法是什么?

【问题讨论】:

    标签: sql database-design query-optimization


    【解决方案1】:

    这取决于第一个速度有多慢而不是连接的复杂性。仅仅因为您不想(一次)编写更复杂的查询而这样做是一个非常糟糕的主意。性能是做这种性质的事情的唯一真正理由。

    如果第一个速度慢得令人无法接受,那么对点求和的表或字段可能是可接受的非规范化,当且仅当您通过触发器而不是应用程序来更新字段(确保非规范化数字准确性的唯一方法)。您需要测试解决方案,包括额外的更新时间,以确定您是否确实节省了任何处理时间。这可能取决于数字更改的频率。例如,如果您在更新时间上增加一秒并在选择上节省 10 秒,但是您为每个选择进行 10,000 次更新,这不是一个好的优化。但是,如果您将报告从一小时缩短到毫秒,并且只在插入或更新中增加一毫秒,那么它可能是可以接受的。

    如果不使用生产级工作负载和数据对这两种解决方案进行实际编码和测试,就无法回答这个问题。

    【讨论】:

    • 好吧,这是有道理的,它还没有部署,但想知道从什么开始最好的设计。我会选择第一个选项并追求完整性。如果我以后发现问题,我总是可以选择第二个选项。
    【解决方案2】:

    这取决于许多因素,其中大部分取决于您的设置。

    两个最重要的因素是:

    • 您运行查询的频率。请记住,第二种解决方案不仅使用更多磁盘空间(理论上可能会降低性能),而且还需要您在添加记录时注意非规范化结构。尽管可以使用触发器自动执行此操作(取决于 RDBMS),但这仍然是性能开销。
    • 您正在使用的 RDBMS。您的第一个查询可能很难看(我见过更糟糕的情况),但是您确定它很慢吗?获得该问题明确答案的唯一方法是运行查询并使用 EXPLAIN [query] 检查您的 RDBMS 使用的查询计划。

    所以基本上,我会坚持第一个解决方案。有时没有规范化的关系方案是一件好事,但你应该对你的结构进行非规范化,如果你确定,它会给你带来性能提升,并且如果你在类似生产的环境中确定了应用程序的瓶颈。

    【讨论】:

      【解决方案3】:

      如果查询执行得相当好,我会保持原样。在我的书中,一个丑陋的、性能良好的查询胜过冗余。

      使用冗余选项,您需要确保将更新语句封装在事务中,以确保所有内容都得到更新;否则,您将面临数据不同步的风险。

      我曾使用过一些采用冗余路由的旧版应用程序没有事务,当一个表由于某种原因没有更新时,它就会变得一团糟。

      【讨论】:

        猜你喜欢
        • 2016-01-23
        • 1970-01-01
        • 2020-01-21
        • 1970-01-01
        • 2018-01-07
        • 1970-01-01
        • 2012-10-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多