Seb*_*ien 1 ruby ruby-on-rails
我有使用rails的性能问题.当我对这样的控制器进行ajax调用时:
def test
    @hotels = Hotel.all
    render :json => ['hotels' => @hotels ], :include=> [:country, :city]
end
完成大约需要2-5秒.我的数据库中只有40家酒店.我认为它很长......例如,Django上的相同请求将需要400ms
我忘了配置好我的环境吗?
我使用Rails entreprise版本和乘客.
编辑:我的日志文件:
     Started GET "/hotels/test.json" for 172.16.81.1 at Wed Oct 12 22:11:06 +0200 2011
    [paperclip] Duplicate URL for image with /system/:attachment/:id/:style/:filename. This will clash with attachment defined in HotelImage class
    [paperclip] Duplicate URL for thumbnail with /system/:attachment/:id/:style/:filename. This will clash with attachment defined in Hotel class
    [paperclip] Duplicate URL for map with /system/:attachment/:id/:style/:filename. This will clash with attachment defined in Hotel class
    [paperclip] Duplicate URL for thumbnail with /system/:attachment/:id/:style/:filename. This will clash with attachment defined in DestinationAlbumPhoto class
    [paperclip] Duplicate URL for map with /system/:attachment/:id/:style/:filename. This will clash with attachment defined in Destination class
    [paperclip] Duplicate URL for image with /system/:attachment/:id/:style/:filename. This will clash with attachment defined in Continent class
    [paperclip] Duplicate URL for thumbnail with /system/:attachment/:id/:style/:filename. This will clash with attachment defined in Destination class
    [paperclip] Duplicate URL for image with /system/:attachment/:id/:style/:filename. This will clash with attachment defined in Event class
    [paperclip] Duplicate URL for thumbnail with /system/:attachment/:id/:style/:filename. This will clash with attachment defined in HotelAlbumPhoto class
    [paperclip] Duplicate URL for map with /system/:attachment/:id/:style/:filename. This will clash with attachment defined in Event class
      Processing by HotelController#test as JSON
      [1m[36mHotel Load (0.2ms)[0m  [1mSELECT `hotels`.* FROM `hotels`[0m
      [1m[35mCountry Load (0.1ms)[0m  SELECT `countries`.* FROM `countries` WHERE (`countries`.`id` = 3)
      [1m[36mCity Load (0.1ms)[0m  [1mSELECT `cities`.* FROM `cities` WHERE (`cities`.`id` = 2)[0m
    Completed 200 OK in 405ms (Views: 366.1ms | ActiveRecord: 0.3ms)
它写了405ms,但firefox告诉我3,7秒.
我的酒店型号:
class Hotel < ActiveRecord::Base
  cattr_reader :per_page
  @@per_page = 16
  belongs_to :hotel_type
  belongs_to :hotel_theme
  belongs_to :country
  belongs_to :city
  belongs_to :destination
  belongs_to :continent
  has_many :hotel_comments, :dependent => :destroy
  has_many :hotel_album_photos, :dependent => :destroy
  has_many :hotel_activity_values
  has_many :hotel_service_values
  accepts_nested_attributes_for :hotel_album_photos
  has_attached_file :thumbnail, :styles => { :medium => "300x300>", :thumb => "191x134>"} , :default_url => '/images/default/missing.png' 
  has_attached_file :map, :styles => { :medium => "300x300>", :thumb => "191x134>"} , :default_url => '/images/default/missing.png' 
  scope :country, lambda { |country_id|
     self.scoped.where('country_id IN ( ? )', country_id) unless country_id.blank?
  }
  scope :selection, lambda { |selection|
     self.scoped.where('selection = ? ', 1) unless selection.blank?
  }
  scope :city, lambda { |city_id|
      self.scoped.where('city_id IN ( ? )', city_id) unless city_id.blank?
  }
  scope :hoteltype, lambda { |type|
      self.scoped.where('hotel_type_id IN ( ? )', type) unless type.blank?
   }
  scope :theme, lambda { |theme|
      self.scoped.where('hotel_theme_id IN ( ? )', theme) unless theme.blank?
   }
  scope :prices, lambda { |prices|
      condition = []
      prices.each do |price|
        pricesArray = price.split('-')
        condition.push '(price BETWEEN ' + pricesArray[0] + ' AND ' + pricesArray[1] + ')'
      end
      self.scoped.where(condition.join(' OR ')) 
   }
   scope :order_by_price, lambda { |direction|
     self.scoped.order('price ' + direction)
   }
   scope :order_by_rate, lambda { |rate|
     self.scoped.order('global_rate ' + rate)
   }
   scope :services, lambda { |services|
      {:joins => [:hotel_service_values ]  , :conditions => { :hotel_service_values => {:hotel_service_id  => services}}}
   }
  scope :limiter, lambda { |limiter|
      self.scoped.limit(limiter)
   }
end
谢谢你的帮助.
看着你的代码,我的猜测是你有一个简单的"N + 1"问题.
即你加载@hotels到一个数组,但当你来生产json你加载country和城市for each酒店.
因此,对于您的40家酒店,您必须总共进行81次数据库查询.
这可以通过在include加载时执行来简单地改进.
在旧的风格
Hotel.all(:include => [:country, :city])
在Rails 3风格
Hotel.includes(:country, :city).all
通过此更改,您应该只进行3次数据库调用.
有关详细信息,请参阅Eager Loading上的Rails指南.
| 归档时间: | 
 | 
| 查看次数: | 444 次 | 
| 最近记录: |