这更多的是一种偏好,但我想知道人们认为执行的最佳选项是什么。我有一个问题、答案和观点(因为我需要跟踪哪个用户提出了观点)
表转储
Question:
id
title
Answer:
id
question_id
user_id
response
Point_Answer:
id
answer_id
user_id
points因此,在此布局中,要获得Top Answer将需要一个复杂的连接序列。
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 get。所以基本上是一个额外的更新。基本上,这是“完整性与冗余性”和一些优化,更好的方法是什么?
发布于 2010-09-28 02:11:27
这将取决于第一个连接的速度有多慢,而不是连接的复杂性。如果仅仅因为您不想编写(一次)更复杂查询而这样做,这将是一个非常糟糕的想法。性能是做这类事情的唯一真正原因。
如果第一个速度慢得不可接受,那么当且仅当您通过触发器而不是从应用程序更新字段时,求和点的表或字段才是可接受的反规格化(确保反规格化数字准确性的唯一方法)。您需要测试解决方案,包括额外的更新时间,以确定是否确实节省了任何处理时间。这可能取决于数字更改的频率。FOr实例如果您将更新时间增加1秒,并在select上节省10秒,但每次selct更新10,000次,这不是一个很好的优化。但是,如果您使报告从一个小时变为毫秒,并且只向insert或update添加了一毫秒,则可能是可以接受的。
如果不使用生产级工作负载和数据对两个解决方案进行实际编码和测试,就无法回答这个问题。
发布于 2010-09-28 02:16:55
它取决于许多因素,其中大部分因素取决于您的设置。
最重要的两个因素是:
所以基本上,我会坚持第一种解决方案。没有规范化的关系模式有时是一件好事,但你应该对你的结构进行反规范化,如果你确定,它会给你带来性能提升,如果你已经在一个类似生产的环境中发现了应用程序中的瓶颈。
发布于 2010-09-28 02:12:14
如果查询执行得相当好,我会让它保持原样。在我的书中,一个丑陋的、性能良好的查询胜过了冗余。
使用冗余选项时,您需要确保将update语句封装在事务中,以确保所有内容都得到更新;否则,您将面临数据不同步的风险。
我使用过一些遗留的应用程序,这些应用程序在没有事务的情况下采用了冗余路由,当一个表由于某种原因没有更新时,它就会变得混乱。
https://stackoverflow.com/questions/3806476
复制相似问题