Ruby on rails Rails 3.2-查询性能(Postgres)

Ruby on rails Rails 3.2-查询性能(Postgres),ruby-on-rails,performance,postgresql,optimization,Ruby On Rails,Performance,Postgresql,Optimization,背景: 我正在创建一个仪表板作为一个项目,我有一个查询,我认为这将是一个很大的性能问题: <% for outlet in @outlets %> <% if Monitoring.where(:outlet_id => outlet.id).where('date(created_at) = ?', Date.today).exists? %> <li> <a class="done" href="

背景:

我正在创建一个仪表板作为一个项目,我有一个查询,我认为这将是一个很大的性能问题:

<% for outlet in @outlets %>
    <% if Monitoring.where(:outlet_id => outlet.id).where('date(created_at) = ?', Date.today).exists? %>
        <li>
            <a class="done" href="<%= outlet_url(outlet) %>" rel="tooltip" title="<%= outlet.name %>"></a>
        </li>
    <% else %>
        <li>
            <a href="<%= outlet_url(outlet) %>" rel="tooltip" title="<%= outlet.name %>"></a>
        </li>
    <% end %>
<% end %>

outlet.id)。其中('date(created_at)=?',date.today)。是否存在?%>
  • 我要做的是在一页上画一系列的点。如果锚定标记有一个类done,它将显示为绿色,如果没有,它将显示为红色(通过CSS完成)

    除了这里明显的枯燥问题之外,这个查询非常繁重,所以我正在寻找改进它的方法

    一个网点每天至少被监控一次(一个网点有很多:监控)。对于每个插座,我需要检查是否在特定的一天对其进行了监控,并相应地输出HTML

    如果有人能帮我,那就太好了。 (此外,如有任何关于缓存的建议,我们将不胜感激)

    提前干杯:)。

    也许可以试试:

    <% @outlets.includes(:monitorings).each do |outlet| %>
      <% css_class = outlet.monitorings.any? { |m| m.created_at == Date.today } ? 'done' : '' %>
      <li><%= link_to '', outlet_url(outlet), :class => css_class, :rel => "tooltip", :title => outlet.name %></li>
    <% end %>
    
    
    
  • css_类,:rel=>“工具提示”,:title=>outlet.name%>

  • 它将执行一个大查询。

    缓存它的一个好方法是使用回调对数据库进行非规范化。在您的Outlet模型中,您可以添加一个名为last_monitored_on的字段;保存监控器时,使用日期更新相应的插座型号。这样,您就不必查询监视器了


    你也可以考虑缓存那个页面片段,并让它每天过期。

    你可以对当前的监视器进行条件关联,然后使用包含来获取原始查询上的关联的当前监视。
    class Outlet
      has many :current_monitorings, :class_name => "Monitoring",
        :conditions => proc { [ 'monitorings.created_at > ?', Time.now.midnight ] }
    end
    
    @outlets = Outlet.includes(:current_monitorings)
    
    @outlets.each do |outlet|
      if outlet.current_monitorings.empty?
        # the no monitor today case
      else
        # it's been monitored today
      end
    end
    
    在Postgres级别,您可能会受益于监控索引(outlet_id,created_At),以支持包含的外部连接


    顺便说一句,在视图中执行数据库查询是不好的风格。将域逻辑放在模型中,让控制器执行查询并将结果提供给表示层。

    顺便说一句,这实际上不应该是一个非常昂贵的查询,所以在演示实际问题之前,不要担心缓存问题。我认为这是我最喜欢的解决方案。在缓存方面,我认为这是绝对必要的。同一页面上可能有多达2000家分店,每5分钟左右刷新一次。您会推荐什么作为缓存此数据的最佳方法?使用一个外部联接获取2000行不是一个昂贵的操作。首先实施,然后衡量。我不会推荐cache,因为我怀疑你是否需要它。