首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >DB表优化join与repeat列

DB表优化join与repeat列
EN

Stack Overflow用户
提问于 2010-09-28 01:58:27
回答 3查看 281关注 0票数 1

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

表转储

代码语言:javascript
运行
复制
Question:
  id
  title

Answer:
  id
  question_id
  user_id
  response

Point_Answer:
  id
  answer_id
  user_id
  points

因此,在此布局中,要获得Top Answer将需要一个复杂的连接序列。

代码语言:javascript
运行
复制
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

如果我像这样改变它:

代码语言:javascript
运行
复制
Question:
  id
  title

Answer:
  id
  question_id
  user_id
  response
  points

Point_Answer:
  id
  answer_id
  user_id
  points

查询的负担会更小

代码语言:javascript
运行
复制
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。所以基本上是一个额外的更新。基本上,这是“完整性与冗余性”和一些优化,更好的方法是什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-09-28 02:11:27

这将取决于第一个连接的速度有多慢,而不是连接的复杂性。如果仅仅因为您不想编写(一次)更复杂查询而这样做,这将是一个非常糟糕的想法。性能是做这类事情的唯一真正原因。

如果第一个速度慢得不可接受,那么当且仅当您通过触发器而不是从应用程序更新字段时,求和点的表或字段才是可接受的反规格化(确保反规格化数字准确性的唯一方法)。您需要测试解决方案,包括额外的更新时间,以确定是否确实节省了任何处理时间。这可能取决于数字更改的频率。FOr实例如果您将更新时间增加1秒,并在select上节省10秒,但每次selct更新10,000次,这不是一个很好的优化。但是,如果您使报告从一个小时变为毫秒,并且只向insert或update添加了一毫秒,则可能是可以接受的。

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

票数 5
EN

Stack Overflow用户

发布于 2010-09-28 02:16:55

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

最重要的两个因素是:

  • 运行查询的频率。请记住,第二种解决方案不仅使用更多的磁盘空间(从理论上讲,这可能会降低性能),还要求您在添加记录时注意非规范化结构。虽然这可以使用触发器自动执行(取决于关系型数据库),但这仍然是一种性能开销。
  • 您正在使用的关系型数据库。你的第一个查询可能很难看(我见过更糟的),但你确定它很慢吗?获得该问题确切答案的唯一方法是运行查询,并使用EXPLAIN查询检查您的RDBMS使用什么查询计划。

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

票数 2
EN

Stack Overflow用户

发布于 2010-09-28 02:12:14

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

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

我使用过一些遗留的应用程序,这些应用程序在没有事务的情况下采用了冗余路由,当一个表由于某种原因没有更新时,它就会变得混乱。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3806476

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档