1

N + 1 の問題を回避するために、「bullet」という gem を使用しています。

私の以前のコードは

@communities = Community.scoped.page(params[:page]).order("created_at DESC")

次に、このエラーが発生していました

N+1 Query detected
  Community => [:platform]
  Add to your finder: :include => [:platform]

N+1 Query detected
  Community => [:genre]
  Add to your finder: :include => [:genre]

N+1 Query detected
  Community => [:tags]
  Add to your finder: :include => [:tags]

次に、70 を超える SQL を含むページを表示するのに約 650 ミリ秒かかりました。
なので、これに変更しました

@communities = Community.scoped.page(params[:page]).per(10).order("created_at DESC").includes(:platform, :genre, :tags)

現在、弾丸のアラートはなくなりましたが、750ms かかっており、まだ 70 以上の SQL があります。

何故ですか?

これは、ページを表示するのにかかった時間の結果です (w/rack-mini-profiler)

ここに画像の説明を入力

例えば、それぞれ約30msかかってcommunities/_community いるcount

それぞれcommunities/_communityがこれら 2 つのヘルパーを呼び出します。ここに多数のSQLがある理由でしょうか?

def topic_button(community)
    last_post = community.community_topics.order('last_active_at DESC').first
    if last_post && last_post.last_active_at.today?
        link_to sanitize( "Topics ("+ community.community_topics.count.to_s+")" , community_community_topics_path(community)
    end
end


def uploader_button(community)
    last_post = community.community_uploaders.order('last_active_at DESC').first
    if last_post && last_post.last_active_at.today?
        link_to sanitize("Chat ("+ community.community_uploaders.count.to_s+")" , community_community_uploaders_path(community)
    end
end

アップデート

models/community.rb

paginates_per 10

controllers/communities_controller.rb

@communities = Community.scoped.page(params[:page]).order("created_at DESC")

/views/communities/index.html.erb

<span class='community'>
    <% @communities.each do |community| %>  
        <%= render 'communities/community', :community => community %>
    <% end %>
</span>

/views/communities/_community.html.erb

<div class="Box">
    <div class="List">
        <p class="name"><span><%= community.title %></span></p>
        <%= community.community_name %>
        <p class="img">
        <% if community.community_icon? %>
            <%= link_to image_tag(community.community_icon.url(:medium), :alt => community.title, :style => "width: 250px; height: 250px", :class => 'img-polaroid' ), community_path(community.community_name) %>
        <% end %>
        </p>
        <div class="link">
        <%= platform_search(community.platform.name, community.platform_id) %>
        <%= genre_search(community.genre.name, community.genre_id) %>
        </div>
        <div class="intro">
            <table>
                <tr>
                    <th>Member</th>
                    <td class="border"><%= link_to community.cached_votes_up.to_s , bookmarker_community_path(community.community_name) %></td>
                </tr>
                <tr>
                    <th>Publisher</th>
                    <td class="border"><%= link_to community.publisher, communities_path(:publisher => community.publisher) if !community.blank? %></td>
                </tr>
                <tr>
                    <th class="body">Body</th>
                    <td class="border"><%= community.body.slice(0,55) if !community.blank? %></td>
                </tr>
                <tr>
                    <th class="tag">Tags</th>
                    <td class="border">
                    <% community.tags.each do |tag| %>
                    <span><%= link_to tag.name, {:controller=>'communities', :action=>'index', :tag=>tag.name} %></span>
                    <% end %>
                    </td>
                </tr>
            </table>              
        </div>
        <div class="button">
            <%= topic_button(community) %>
            <%= uploader_button(community) %>
        </div>
        <div class="button">
            <%= chat_button(community) %>
            <%= link_to sanitize('Codes ( ' + community.codes_count.to_s + ' )', community_codes_path(community), :class => 'btn' %>
        </div>
        <div class="follow">
            <span class="bookmark_community" community-id="<%= community.id %>">
            <%= render :partial => "communities/bookmark", :locals => {:community => community} %>
            </span>
        </div>      
    </div>
</div>

application_helper.rb

def topic_button(community)
    last_post = community.community_topics.order('last_active_at DESC').first
    if last_post && last_post.last_active_at.today?
        link_to sanitize("Forum ("+ community.community_topics.count.to_s+")" , community_community_topics_path(community), :class => 'red_button'
    else
        link_to sanitize( "Forum ("+ community.community_topics.count.to_s+")" , community_community_topics_path(community), :class => 'button'
    end
end

def uploader_button(community)
    last_post = community.community_uploaders.order('last_active_at DESC').first
    if last_post && last_post.last_active_at.today?
        link_to sanitize("Uploader ("+ community.community_uploaders.count.to_s+")" , community_community_uploaders_path(community), :class => 'red_button'
    else
        link_to sanitize("Uploader ("+ community.community_uploaders.count.to_s+")" , community_community_uploaders_path(community), :class => 'button'
    end
end

def chat_button(community)
    if !community.comment_threads.last.nil? && community.comment_threads.last.created_at.to_date == Date.current.to_date
        link_to sanitize('Chat', chat_community_path(community), :class => 'red_button'
    else
        link_to sanitize('Chat', chat_community_path(community), :class => 'button'
    end
end

/views/communities/_bookmark.html.erb

<% if user_signed_in? %>
    <% if current_user.voted_up_on? community %>
        <%= link_to(bookmark_community_path(community), :remote => true, :class => 'button') do %>
            <i class="icon-remove"></i>
            Un-Bookmark
        <% end %>
    <% else %>
        <%= link_to(bookmark_community_path(community) ,:remote => true, :class => 'blue_button') do %>
            <i class="icon-bookmark"></i>
            Bookmark
        <% end %>
    <% end %>
<% else %>
    <%= link_to(bookmark_community_path(community) , :class => 'blue_button') do %>
        <i class="icon-bookmark"></i>
        Bookmark
    <% end %>
<% end %>
4

2 に答える 2

1

パフォーマンスを向上させるには、テーブルから必要なフィールド/列を選択してください。

これにより、各リクエストに使用されるシステム メモリが節約され、データベースからリクエストをフェッチする時間も節約されます。

rails3 を使用している場合は「select」メソッドを使用するか、rails2 の場合は find メソッドで「select」オプションを使用できます。

メモリ オブジェクト キャッシング システムを使用している場合は、特定のフィールドを選択しないでください。

于 2013-07-18T08:05:48.050 に答える
1

I will suggest you to please go through you development log. You will definitely find how much time is taken by which process or partial. First clear your development log. And then refresh your page/action.

Another suggestion is use a class variable for methods like current_user,user_signed_in? . These are executed so many times.

@current_user = current_user

And then no need to use current_user anywhere. Just replace it to @current_user. In your development.log you will find the difference.

Similarly, for more speed you can use caching.

于 2013-07-18T06:46:48.107 に答える