在ajax调用中降低Authlogic / find的成本

时间:2010-08-23 10:12:22

标签: ruby-on-rails

我注意到我的网站上的AJAX调用很慢,看着NewRelic RPM我注意到大部分费用来自Authlogic/find

我想这是因为rails每次都需要查找用户(即使是在AJAX调用上),但147微秒似乎非常慢。

Category    Segment     % Time      Avg Calls (per Txn)     Avg Exclusive Time (ms)
Custom       Authlogic/find      77      1.0     147
Controller  LikesController#toggle  13  1.0     25
Database    SQL - SHOW  4.9     1.5     9.3
Database    SQL - OTHER     1.1     3.7     2.1
ActiveRecord    User#find   0.8     1.0     1.5
View    application.html.haml Template  0.7     0.2     1.3
View    _like.html.haml Template    0.5     0.8     0.89
ActiveRecord    ActiveRecord::SessionStore::Session#find    0.4     1.0     0.69 

这是我的代码:

class LikesController < ApplicationController
  ## commented this part out in the hopes of reducing authlogic needs, since it's simple for me to check for current_user myself.

  # access_control do
  #   allow :admin
  #   allow logged_in, :to => [:toggle]
  # end
  before_filter :check_if_admin, :except => [:toggle]

  def index
    @likes = Like.all
  end

  def toggle
    if !current_user
      render :nothing => true and return
    end

    like = Like.find(:first, :conditions => "user_id = #{current_user.id} and likable_id = #{params[:likable_id]} and likable_type = '#{params[:likable_type]}'")
    if like != nil
      like.destroy
      @current_user_likes_likable = false
    else
      like = Like.new(:likable_id => params[:likable_id], :likable_type => params[:likable_type], :user => current_user)
      like.save
      @current_user_likes_likable = true
    end
    @likable_id = params[:likable_id]
    @likable_type = params[:likable_type]
    #@likable = Kernel.const_get(params[:likable_type]).find(params[:likable_id])
    render "shared/like"
  end
...

此处还有在ApplicationController中定义current_user的地方:

class ApplicationController < ActionController::Base
  helper :layout
  helper_method :current_user_session, :current_user, :current_user_is_admin

  private
    def current_user_session
      return @current_user_session if defined?(@current_user_session)
      @current_user_session = UserSession.find
    end
    def current_user
      return @current_user if defined?(@current_user)
      @current_user = current_user_session && current_user_session.record
    end

2 个答案:

答案 0 :(得分:0)

您使用的数据库是什么?如果您的查询运行缓慢,首先要看的是indexes on your database。我不知道find方法运行的是什么SQL,但这是一个很好的起点。确保列上有正确的索引(可能需要多个索引)。

答案 1 :(得分:0)

我在另一个应用中遇到同样的问题。我使用authlogic构建了一个干净的项目:http://github.com/josei/authlogic_rpm

Newrelic已安装并正常运行,因此您可以快速检查authlogic的性能。正如您所看到的,性能非常好(使用sqlite3大约50ms),因此开销必须在其他地方(可能是插件)。