优化 sql 查询 rails
optimize sql query rails
在帖子索引页面上,我以这种方式列出所有帖子:
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 个帖子
当我第一次在开发环境中加载页面时,
rack-mini-profiler 这次显示:1441.1 ms
重新加载几次后:~700 毫秒
我能以某种方式减少 sql 请求的时间和数量吗?
如果有帮助的话,这里是 rmp 图片:
您可以通过以下方式减少 sql 查询的数量:
包括user
和comments
,因为你好像在显示头像的时候用到了
将 post.comments.count
更改为 post.comments.size
虽然大小、计数、长度是数组的同义词,但对于活动记录关系或关联而言,它们并不相同:
length
加载关联(除非已经加载)和returns数组的长度
count
执行 select count(*) query
是否加载关联
如果关联已加载,size
使用 length
,否则使用 count
。
在您的情况下,评论关联已加载,但由于您使用的是 count
,因此实际上并未使用
在参考列(您的情况下的评论)上添加索引可能会有所帮助。
add_index :posts, :comment_id
此外,除了打印记录数之外,您实际上并未将 comments
集合用于任何其他用途。如果确实如此,请使用 counter_cache (4.1.2.3
) 而不是查询评论(评论数量将在父记录 Post
中可用)。
同时考虑 client side alternative 到 time_ago_in_words
。如果您以后决定缓存整个 section/page.
,它也会有所帮助
最后只检索您要使用的字段。在这种情况下,我可以想象 Post
包含大量内容文本并且它没有在任何地方使用(但仍然需要从 DB 传输)。
在帖子索引页面上,我以这种方式列出所有帖子:
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 个帖子
当我第一次在开发环境中加载页面时, rack-mini-profiler 这次显示:1441.1 ms
重新加载几次后:~700 毫秒
我能以某种方式减少 sql 请求的时间和数量吗?
如果有帮助的话,这里是 rmp 图片:
您可以通过以下方式减少 sql 查询的数量:
包括
user
和comments
,因为你好像在显示头像的时候用到了将
post.comments.count
更改为post.comments.size
虽然大小、计数、长度是数组的同义词,但对于活动记录关系或关联而言,它们并不相同:
length
加载关联(除非已经加载)和returns数组的长度count
执行select count(*) query
是否加载关联
如果关联已加载,size
使用length
,否则使用count
。
在您的情况下,评论关联已加载,但由于您使用的是 count
,因此实际上并未使用
在参考列(您的情况下的评论)上添加索引可能会有所帮助。
add_index :posts, :comment_id
此外,除了打印记录数之外,您实际上并未将 comments
集合用于任何其他用途。如果确实如此,请使用 counter_cache (4.1.2.3
) 而不是查询评论(评论数量将在父记录 Post
中可用)。
同时考虑 client side alternative 到 time_ago_in_words
。如果您以后决定缓存整个 section/page.
最后只检索您要使用的字段。在这种情况下,我可以想象 Post
包含大量内容文本并且它没有在任何地方使用(但仍然需要从 DB 传输)。