繁体   English   中英

Rails数据库性能调优

[英]Rails database performance tuning

目前,我正在使用非常大的mysql2数据库进行很多工作,尽管我已经索引了我认为适当的字段,但是某些查询的返回时间非常慢。

我有两个引起问题的模型CommentCommenter

现在,有一个has_many关系CommenterComment ,但我的查询依赖于寻找每个评论的评论者的用户名。 因此,我将运行以下内容:

c = Blog.first.comments ##this bit runs fine, I indexed the "blog_id" field on Comments
c.collect {|c| c.commenter.username}

为了解决速度问题,我在Commenter模型的commenter_id字段上创建了一个索引。 但是它仍然运行非常缓慢。

有人知道我可以做些什么,那将有助于提高查询速度吗?

在索引commenter_id帮助,当你想找到一个给定的评论commenter_id (“找到我提出的所有意见乔”)。

但是,当您使用c.commenter您正在搜索用户,大概是其id等于评论的commenter_id id列上应该已经有一个索引。 surefire的方法是采用实际生成的sql语句(在开发中,这些语句在development.log中),并在其上使用解释(例如)

explain select * from comments where id = 12345

鉴于您很难创建一个表而不在其id列上建立索引,因此最有可能的罪魁祸首是急于加载-如果某条帖子包含500条评论,则以上代码将逐个获取关联的用户,而那500条往返数据库的总和

c.includes(:commenter).collect {...}

要么

c.eager_load(:commenter).collect {...}

将解决此问题(以上代码段假定您正在使用导轨3)。

Collect将为每个带有所有字段的评论者一次加载ActiveRecord对象。 包含/急于加载将使用一个查询来加载它们,这将有助于提高速度,但是如果您想要绝对最佳的性能,并且只需要名称,那么最好通过以下方式更直接地接触到SQL:

c         = Blog.first.comments
user_ids  = c.collect(&:commenter_id)
usernames = Commenter.where(['commenter_id IN (?)',user_ids]).select('username').collect(&:username)

首先,您在这里做了太多不必要的查询c.collect {|c| c.commenter.username} c.collect {|c| c.commenter.username}我认为热切的加载可以为您提供帮助。 观看此http://railscasts.com/episodes/23-counter-cache-column?autoplay=true

我使用热切的负载算出了它,这不是RaskolnikOFF发布的链接,而是之前的rails-cast, http: //railscasts.com/episodes/22-eager-loading(仍然为您提供了推动我前往回答)

显然我正在寻找以下内容:

b = Blog.find(:first, :include=>{:comments => :commenter})
b.comments.collect {|c| c.commenter.username}

第一行加载第一个博客及其所有关系(并返回博客)。 因此,当我拨打第二行时,所有内容均已加载并等待访问。

哪种方法比我最初做的更好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM