0

我正在完成我的第一个真正的 Rails 项目,我需要一些时间回去尝试提高效率/性能。

例如,我有一个模型Section(下面简化),它是递归的,任何给定的部分都可以是任何其他部分的父和/或子。

部分

class Section < ActiveRecord::Base
  default_scope order('sections.id ASC')

  attr_accessible               :name, 
                                :parent_id

  def children(all_sections)
    # ::ORIGINAL CODE::
    # return Section.where(parent_id: id)

    # ::OPTIMIZED CODE THAT REMOVES ADDITIONAL DB CALLS::
    children = []

    all_sections.each do |sec|
      children.push(sec) if sec.parent_id == id
    end

    return children
  end
end

最初,我会获取所有部分,循环遍历它们并调用children每个部分以获取特定部分的子项。我更改了上面的代码,所以现在我传入所有部分并循环它们以获取子部分。

页脚.html.haml

- @sections = Section.all

%footer
  - @sections.each do |section|
    - if section.parent_id == 0
      %nav{:id=>"#{section.name}"}
        %h1
          = section.name
        %ul
          - section.children(@sections).each do |subsection|
            %li
              = subsection.name

由于这是页脚并在每个页面上呈现,我希望删除额外的 DB 调用会提高性能,它确实看起来,但不是很多,可能是 5-10 毫秒。

我想知道的是,我是否走在正确的轨道上,我能做些什么来使它变得更好?

4

2 回答 2

0

除了 ActiveRecord 级别的优化之外,您是否考虑Section过按时间戳缓存 s?这样,您只有在数据库更新后才返回数据库Section(因此缓存过期)。

是关于缓存的一个很好的参考。使用 HTTP 缓存,您甚至根本不需要访问 Rails 堆栈。

于 2013-10-19T17:46:46.650 回答
0

我认为还有另一种选择,即 EagerLoading,

在截面模型中:

class Section < ActiveRecord::Base

  attr_accessible               :name, 
                                :parent_id

  #Associations
  has_many :subsections, :class_name => "Section", :foreign_key => :parent_id

  #Scopes
  default_scope order('sections.id ASC')
  scope :only_parent, -> { where(:parent_id => 0) }
end

然后在部分控制器中

class SectionsController
  def footer
    @sections = Section.includes(:subsections).only_parent
  end
end

现在在视图中,

%footer
  - @sections.each do |section|
      %nav{:id=>"#{section.name}"}
        %h1
          = section.name
        %ul
          - section.subsections.each do |subsection| #(now this will not execute any query, as this has already been eager loaded)
            %li
              = subsection.name
于 2013-10-19T18:32:14.687 回答