优化sql查询rails

时间:2015-01-03 15:43:23

标签: sql ruby-on-rails activerecord

在帖子索引页面上,我以这种方式列出所有帖子:

posts_controller.rb

def index
  @posts = Post.includes(:comments).paginate(:page => params[:page]).order("created_at DESC")
end

index.html.erb

 <%= render @posts %>

_post.html.erb

<%= gravatar_for post.user, size:20 %>
<%= link_to "#{post.title}", post_path(post) %>
<%= time_ago_in_words(post.created_at) %> 
<%= post.comments.count %>
<%= post.category.name if post.category %>
每页35个帖子

当我第一次在dev env中加载页面时, rack-mini-profiler显示此时间: 1441.1 ms

重新加载后: ~700 ms

我可以以某种方式减少这个时间和sql请求的数量吗?

如果有帮助,这里是rmp图片:

enter image description here

enter image description here

3 个答案:

答案 0 :(得分:5)

您可以通过以下方式减少sql查询的数量:

  • 包括user以及comments,因为您在展示重力数据时似乎正在使用

  • post.comments.count更改为post.comments.size

虽然大小,数量,长度是数组的同义词,但对于活动记录关系或关联,它们并不相同:

  • length加载关联(除非它已经加载)并返回数组的长度
  • count执行select count(*) query是否加载关联
  • 如果加载关联,则
  • size使用length,否则使用count

在您的情况下,评论关联已加载,但由于您使用的是count,因此未实际使用

答案 1 :(得分:1)

此外,除了打印记录数以外,您实际上似乎并没有使用comments集合。如果情况确实如此,请使用counter_cache4.1.2.3)而不是查询评论(评论数量将在父记录Post中提供)。

还要考虑client side alternativetime_ago_in_words。如果您以后决定缓存整个部分/页面,它也会有所帮助。

最后只检索您将要使用的字段。在这种情况下,我可以想象Post包含大量内容文本,并且不在任何地方使用(但仍需要从数据库传输)。

答案 2 :(得分:0)

在引用列上添加索引(在您的情况下为注释)可能有所帮助。

add_index :posts, :comment_id