【问题标题】:How do I optimize a query when includes won't work?当包含不起作用时,如何优化查询?
【发布时间】:2015-01-09 22:35:58
【问题描述】:

我有这些each 循环:

<% relation_types.each do |relation| %>

            <% if !current_user.memberships.where(relation: relation).empty? %>
                <% current_user.memberships.where(relation: relation).each do |membership| %>
<% end %>

两者都会在每次页面加载时生成此日志:

 User Load (32.1ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = 1  ORDER BY "users"."id" ASC LIMIT 1
  FamilyTree Load (6.2ms)  SELECT  "family_trees".* FROM "family_trees"  WHERE "family_trees"."user_id" = $1 LIMIT 1  [["user_id", 1]]
   (3.0ms)  SELECT "memberships"."relation" FROM "memberships"  WHERE "memberships"."family_tree_id" = $1  [["family_tree_id", 1]]
   (3.7ms)  SELECT COUNT(*) FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'great_grandmother'  [["user_id", 1]]
   (17.9ms)  SELECT COUNT(*) FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'great_grandfather'  [["user_id", 1]]
   (3.3ms)  SELECT COUNT(*) FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'grandmother'  [["user_id", 1]]
   (1.8ms)  SELECT COUNT(*) FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'grandfather'  [["user_id", 1]]
   (3.5ms)  SELECT COUNT(*) FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'mom'  [["user_id", 1]]
   (14.9ms)  SELECT COUNT(*) FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'dad'  [["user_id", 1]]
   (2.8ms)  SELECT COUNT(*) FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'aunt'  [["user_id", 1]]
   (3.9ms)  SELECT COUNT(*) FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'uncle'  [["user_id", 1]]
  Membership Load (3.4ms)  SELECT "memberships".* FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'uncle'  [["user_id", 1]]
   (2.7ms)  SELECT COUNT(*) FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'sister'  [["user_id", 1]]
   (14.2ms)  SELECT COUNT(*) FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'brother'  [["user_id", 1]]
  Membership Load (3.2ms)  SELECT "memberships".* FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'brother'  [["user_id", 1]]
   (3.7ms)  SELECT COUNT(*) FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'cousin'  [["user_id", 1]]
   (4.3ms)  SELECT COUNT(*) FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'daughter'  [["user_id", 1]]
   (3.8ms)  SELECT COUNT(*) FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'son'  [["user_id", 1]]
   (5.7ms)  SELECT COUNT(*) FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'niece'  [["user_id", 1]]
   (3.0ms)  SELECT COUNT(*) FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'nephew'  [["user_id", 1]]
  Membership Load (3.9ms)  SELECT "memberships".* FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'nephew'  [["user_id", 1]]
   (2.4ms)  SELECT COUNT(*) FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'granddaughter'  [["user_id", 1]]
   (10.7ms)  SELECT COUNT(*) FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'grandson'  [["user_id", 1]]
   (4.7ms)  SELECT COUNT(*) FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'great_granddaughter'  [["user_id", 1]]
   (5.4ms)  SELECT COUNT(*) FROM "memberships"  WHERE "memberships"."user_id" = $1 AND "memberships"."relation" = 'great_grandson'  [["user_id", 1]]

这是Membership 的架构和关联:

# == Schema Information
#
# Table name: memberships
#
#  id             :integer          not null, primary key
#  family_tree_id :integer
#  user_id        :integer
#  created_at     :datetime
#  updated_at     :datetime
#  relation       :string(255)

class Membership < ActiveRecord::Base
  attr_accessible :user_id, :relation

  belongs_to :family_tree
  belongs_to :user

end

如何优化?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 optimization query-optimization


    【解决方案1】:

    按关系分组怎么样?

    在您的控制器中:

    @memberships_grouped_by_relations = current_user.memberships.group_by(&:relation)
    

    在你看来:

    <% @memberships_grouped_by_relations.each do |relation, memberships| %>
      <% if memberships.any? %>
        <% memberships.each do |membership| %>
        <% end %>
      <% end %>
    <% end %>
    

    【讨论】:

      【解决方案2】:

      为什么不用 1 个查询 预加载所有成员资格:

      memberships = current_user.memberships.where(relation: relation_types)
      

      然后稍后使用 ruby​​ 进行所有过滤/选择

       <% relation_types.each do |relation| %>
         <% memberships_for_relation = memberships.select { |m| m.relation == relation } %>
      
         <% if !memberships_for_relation.size > 0 %>
           <% memberships_for_relation.each do |membership| %>
        <% end %>
      

      您可能想编写一些帮助程序来使这段代码更好,但这里的主要思想是一次加载所有必需的成员资格。

      【讨论】:

        猜你喜欢
        • 2011-02-11
        • 2013-11-15
        • 1970-01-01
        • 2016-04-07
        • 1970-01-01
        • 1970-01-01
        • 2014-08-10
        • 1970-01-01
        • 2015-09-27
        相关资源
        最近更新 更多