【问题标题】:Sequel query causes script to hang and causes computer to slow down续集查询导致脚本挂起并导致计算机变慢
【发布时间】:2016-06-17 13:50:05
【问题描述】:

我有以下代码:

team_articles = user.npt_teams.to_a.inject({}) {|arts,team|
    arts.merge({ team.name =>
    NptArticle.join(:npt_authors).join(:users).join(:npt_teams).where(:npt_teams__id => team.id).to_a.uniq})
  }

这会导致我的终端停止响应并且我的 Macbook 速度变慢。

在 mysqlworkbench 中它会立即得到响应。

一个建议是创建 NptArticle 对象的较轻版本,但我不太确定如何创建一个拉更少列的版本,因此任何解决此问题的建议都会很棒。

这是the table

生成的SQL是:

SELECT * FROM `npt_articles` INNER JOIN `npt_authors` INNER JOIN `users` INNER JOIN `npt_teams` WHERE (`npt_teams`.`id` = 1)

我很想升级 Ruby 版本,但我不能。我正在处理一个旧的代码库,这是它使用的 Ruby 版本。有计划在未来使用更现代的工具进行重建,但目前这是我必须使用的。

Results 来自:

EXPLAIN SELECT * FROM npt_articles INNER JOIN npt_authors INNER JOIN users INNER JOIN npt_teams WHERE (npt_teams.id = 1);

【问题讨论】:

  • 能否请您提供表格描述以及您在其上创建的任何索引?
  • 你真的,迫切需要更新那个 Ruby。它生成什么查询? .to_sql 方法通常在这里通知。在这里使用merge 是完全不合适的,您在此过程中生成了 N 个哈希值。使用 arts[team.name] = ... 并将 arts 作为您块中的最后一件事。
  • 你能把 EXPLAIN SELECT * FROM npt_articles INNER JOIN npt_authors INNER JOIN users INNER JOIN npt_teams WHERE (npt_teams.id = 1) 的结果贴出来

标签: mysql ruby sequel ruby-1.8.7


【解决方案1】:

所以对于npt_team.id =1,您正在为所有人执行交叉连接:

npt_articles
npt_authors
users

如果文章、作者和用户的数量适中,您将获得大量结果,因为连接不受限制。通常,你会使用类似的东西:

INNER JOIN `npt_authors` ON (npt_articles.ID=npt_authors.articleID) 

(这取决于您的数据库如何关联)。

此外,您需要在将表相互关联的字段上建立索引,这也会加快处理速度。

查看EXPLAIN SELECT 的行列。这就是连接的每个部分正在处理的行数。要估计处理的总行数,请将这些数字相乘。 1 x 657 x 269723 x 956188 = rather a lot.

我不是 Ruby 专家,所以也许其他人可以发布您的操作方法。

【讨论】:

  • 天哪,很多,我想它很慢也就不足为奇了。
  • 发生这种情况是因为数据库不会自动知道如何将各种表关联在一起,因此它目前正在将所有内容与其他所有内容连接起来。
猜你喜欢
  • 2014-07-05
  • 2013-11-20
  • 1970-01-01
  • 2015-01-27
  • 2018-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多