[英]Rails database performance tuning
目前,我正在使用非常大的mysql2数据库进行很多工作,尽管我已经索引了我认为适当的字段,但是某些查询的返回时间非常慢。
我有两个引起问题的模型Comment
和Commenter
。
现在,有一个has_many
关系Commenter
和Comment
,但我的查询依赖于寻找每个评论的评论者的用户名。 因此,我将运行以下内容:
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.