optimize sql query rails

自闭症网瘾萝莉.ら 提交于 2019-12-13 02:27:20

问题


On posts index page I list all posts this way:

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 posts per page

When I first load the page in dev env, rack-mini-profiler shows this time: 1441.1 ms

after a few reloads: ~700 ms

Can I somehow decrease this time and number of sql requests?

Here're rmp images if it helps:


回答1:


You could decrease the number of sql queries by:

  • including user as well as comments, since you seem to be using that when displaying the gravatar

  • changing post.comments.count to post.comments.size

While size, count, length are synonymous for arrays, for active record relations or associations they are not the same:

  • length loads the association (unless it is already loaded) and returns the length of the array
  • count does a select count(*) query whether the association is loaded or not
  • size uses length if the association is loaded and count if not.

In your case the comments association is loaded, but because you are using count, it's not actually used




回答2:


Further, you don't actually seem to be using the comments collection for anything other than printing the number of records. If that's indeed the case, use counter_cache (4.1.2.3) instead of querying for the comments (the number of comments will be available in the parent record Post).

Also consider a client side alternative to time_ago_in_words. It will also help if you later decide to cache the entire section/page.

And finally retrieve only the fields you're going to use. In this case, I can imagine the Post contains a large amount of text for the content and it's not used anywhere (but still needs to be transmitted from the DB).




回答3:


Adding an index on the reference column (comments in your case) might help.

add_index :posts, :comment_id


来源:https://stackoverflow.com/questions/27756532/optimize-sql-query-rails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!