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

发布于 2024-08-19 03:52:46 字数 168 浏览 4 评论 0原文

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

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

我有一个页面,预计每个页面加载最终会访问数据库大约 20 次。这令人担忧,但不知道我是否应该担心,或者我可以做些什么来减轻负担?

If you have a Rail app with many complex associated models, what techniques do you employ to reduce database queries?

In fact, I'll extend that question a little further and ask, what do you consider "too many" queries for any page?

I have a page that I expect will end up hitting the database about 20 times each page load. That concerns be but don't know whether it should concern me, or what I can do to reduce the load?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

故人爱我别走 2024-08-26 03:52:46

查看:bullet

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

它确实会减慢开发模式,因此当您不进行性能调优时,请务必禁用它。

当我们这样做时,还可以查看:rails_indexes

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

快乐调音。

Check out: bullet

Its a great way to identify n+1 queries and it offers suggestions to minimize it.

It does slow down development mode, so be sure to disable it when you are not performance tuning.

While we are at it, also checkout: rails_indexes

A simple way to identify which indexes your app could be missing.

Happy tuning.

泪意 2024-08-26 03:52:46

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

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

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

...并且显示视图会执行类似以下操作:

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

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

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

与往常一样,检查控制台以了解查询时间等。

One common practice is judicious use of the include => :association option.

For instance on a controller you might do:

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

...and the show view would do something like:

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

This will create a query for every call to product. But if you declare the association included as follows, you get eagerly-loaded associations in one query:

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

As always, check your console for query times and such.

橪书 2024-08-26 03:52:46

如果您只需要显示数据,我正在使用 :joins 和 :select 选项。
我发现命名范围非常有用,可以定义所有可能的 :join 和一个 :select_columns 命名范围。示例

    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)

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

I am useing :joins and :select options if you need just to display data.
I found very useful named_scope to define all possible :joins and one :select_columns named_scope. Example

    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

So now you can easly build queries like this:

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)

I consider this is not the best and safest way, but in my case it really minify query count that executes per request and there are no errors rised about some wrong generated queries yet.

转身以后 2024-08-26 03:52:46

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

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

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

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

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

It is really difficult to estimate a limit for queries. This is related at the concept/design of your application.

If you don't have to reload the whole page, I suggest you consider javascript (or rjs) in order to update only the data you need. This should be also an UI improvement, your users will love it!

Check the SQL generated from your ActiveRecord queries. Be sure that everything is like expected.

Consider to denormalize your db in order to improve performance. (be carefully)

This is what I see from the "code side".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文