如果包含不起作用,如何优化查询?

时间:2014-11-12 22:19:28

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

我有这些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]]

这是架构&amp; 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

如何优化此功能?

2 个答案:

答案 0 :(得分:2)

按关系分组怎么样?

在您的控制器中:

@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 %>

答案 1 :(得分:1)

为什么不使用 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 %>

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