【问题标题】:Design decision? 4 minute report... tying up the server设计决策? 4 分钟报告... 占用服务器
【发布时间】:2011-05-28 01:22:06
【问题描述】:

在我的 RoR 应用程序中运行一些报告最多需要 4 分钟。从那时起,我的用户在系统停止响应的系统中执行简单任务时遇到了延迟。

我仍在尝试调查问题的主要原因,以查看报告和系统挂起是否相关。有人对我应该如何重构我的报告有任何建议吗?运行它不需要 4 分钟?

到目前为止,我已经考虑过每晚运行一个后台作业,计算我想要的所有数据,这样报告时间就会显着减少。我还没有找到可以使用中间件或内存实例来派生报告而不是通过大型查询访问数据库的解决方案。

技术信息:

  • VPS 运行 384 MB 的 RAM(增加一个足够的解决方法吗?)
  • 报告是 SQL 和一些繁重的 ruby​​ 脚本的组合,用于处理内容,以便以可读的方式显示它们
  • 数据库表包含 2,000 到 30,000 行

技术报告信息

  1. DB-query-1 有 5 个内部连接。它首先运行以创建查找哈希
  2. DB-query-2 有 5 个内部连接。它运行一次并遍历其结果集的每条记录
  3. 对于 (2.) 的每条记录,运行 DB-query-3(包含 5 个内连接)
  4. 对于 (2.) 的每条记录,遍历 (1.) 中的查找哈希以执行一些计算

通过 Anon 的附加信息请求来写这篇文章,我已经可以看到嵌套循环的刺痛......

【问题讨论】:

  • 您为每个报告运行了多少查询?你打的桌子有多大?你在 Ruby 中做了什么样的事情(任何繁重的事情,比如排序?)
  • 添加了其他信息 - 谢谢
  • 是否可以将 (3) 滚动到 (2) 中?这确实会减少正在执行的查询数量。
  • 我的 SQL 不足以解决这个问题……这可能就是它以现在的方式实现的原因。不过,我会在等待其他建议的同时对此进行研究。感谢您的帮助!
  • 您检查过查询的运行时间吗?这可能是关于连接的问题。连接条件中涉及的所有字段都有索引吗?

标签: ruby-on-rails design-patterns database-design


【解决方案1】:

30,000 条记录不算什么。您应该能够在不到 4 秒的时间内对大小如此之大的数据库执行完整转储导出/导入,所以似乎有些不对劲:)

如果您可以向我们提供有关表格、它们的关系以及您的报告内容的一些信息,我相信我们可以就如何改进提供一些具体的建议。

关于绩效报告的一些一般性建议: 不要将 ORM 工具用于报告,除非报告要求非常琐碎(在这种情况下,它会被称为列表,而不是报告)。带着态度去寻找一个手工制作的 SQL。

不要听那些禁止你使用供应商特定 SQL 扩展的狂热者的话。您为这个特定的 dbms 付费(金钱或时间)。 充分利用它!

在数据库中做尽可能多的工作。 (使用扩展时,这变得容易得多)。数据库是为搜索、排序和聚合数据而构建的,它们做得很好。具有 1,000,000 行且平均行大小为 200 字节的表将消耗不到 200 MB。假设磁盘子系统可以提供 50mb/s 的速度,那么对整个表执行 SUM(value) 需要 4 秒。这是理论上的上限。如果您需要更多,则必须预先计算数据以使工作集变得更小(谷歌表示“聚合”和“汇总”)。

这可能意味着编写更长、更复杂的查询。长而复杂的 SQL 经常使优化器感到困惑,以至于它提出了一个次优的执行计划。解决这个问题通常需要对特定 dbms 产品有扎实的经验。不过,拥有一个具有完整引用完整性和约束检查的规范化数据库会使这成为一个不太常见的问题。

不要循环运行查询。如果您的查询需要 1 毫秒才能完成,那么运行 1000 个查询不需要 1 秒。每次调用都必须为网络延迟、数据编组/解组、潜在的锁定问题、解析、获取等“付费”。

(更新)

如果预期(和可接受的)运行时间超过一秒左右,您可以查找一些值并将它们作为文字提供以帮助优化器。这可用于删除不相关的子查询和连接。

尽量减少用户定义的函数。它们混淆了优化器并且经常强制行处理(这是不可扩展的)。

【讨论】:

  • 很棒的提示。我一定会接受你所说的话,我将创建另一篇文章来讨论关于我的数据库架构的设计注意事项。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2019-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多