在Rails应用程序中减少数据库查询的技术

时间:2010-01-28 12:54:17

标签: ruby-on-rails database database-design optimization query-optimization

如果您的Rail应用程序包含许多复杂的关联模型,您采用了哪些技术来减少数据库查询?

事实上,我会进一步扩展这个问题并询问,对于任何页面,您认为“太多”查询是什么?

我有一个页面,我希望每页加载大约20次点击数据库。关注的是,但不知道是否应该关注我,或者我能做些什么来减轻负担?

4 个答案:

答案 0 :(得分:14)

退房:bullet

它是识别n + 1个查询的好方法,它提供了最小化查询的建议。

它确实会降低开发模式的速度,因此请确保在未进行性能调整时将其禁用。

虽然我们在此,但也请结帐:rails_indexes

一种识别应用可能丢失的索引的简单方法。

快乐的调整。

答案 1 :(得分:11)

一种常见做法是明智地使用include => :关联选项。

例如,您可以在控制器上执行以下操作:

def show
    @items = Item.find(:all) 
end

...并且show视图会执行以下操作:

<% @items.each |item| %>
    <%= item.product.title %>
<% end %>

这将为每次产品调用创建一个查询。但是,如果您声明包含如下关联,则会在一个查询中获得急切加载的关联:

def show
    @items = Item.find(:all, :include => :product)
end

与往常一样,检查您的控制台是否有查询时间等。

答案 2 :(得分:0)

我正在使用:加入和:如果只需要显示数据,请选择选项。 我发现非常有用的named_scope来定义所有可能的:连接和一个:select_columns named_scope。实施例

    class Activity < ActiveRecord::Base
      belongs_to :event
      belongs_to :html_template
      has_many :participants

      named_scope :join_event, :joins => :event
      named_scope :join_owner, :joins => {:event => :owner}
      named_scope :left_join_html_template, 
      :joins => "LEFT JOIN html_templates ON html_templates.id = activities.html_template_id"
      named_scope :select_columns, lambda { |columns| {:select => columns}}
      named_scope :order, lambda{ |order| {:order => order}}
end

所以现在你可以轻松地构建这样的查询:

columns = "activities.*,events.title,events.owner_id,owners.full_name as owner_name"
@activities = Activity.join_event.join_owner.order("date_from ASC").select_columns(columns)

我认为这不是最好和最安全的方法,但在我的情况下,它确实缩小了每个请求执行的查询计数,并且还没有出现关于某些错误生成的查询的错误。

答案 3 :(得分:-1)

估计查询限制非常困难。这与您的应用程序的概念/设计有关。

如果您不必重新加载整个页面,我建议您考虑使用javascript(或rjs)以便仅更新所需的数据。这也应该是一个UI改进,你的用户会喜欢它!

检查从ActiveRecord查询生成的SQL。确保一切都像预期的那样。

考虑对数据库进行非规范化以提高性能。 (小心)

这是我从“代码方面”看到的。