尝试使用Rails 2.3和MySQL以最有效的方式获取某些报告的数据。
我们的应用包含用户,优惠和已购买的广告。关系看起来像这样:
class User
has_many :purchased_deals
has_many :deals, :through => :purchased_deals
end
class Deal
has_many :purchased_deals
has_many :users, :through => :purchased_deals
end
class PurchasedDeal
belongs_to :deal
belongs_to :user
end
对于我正在运行的报告,我需要让所有已经购买的用户(即至少有一个已购买的DE),然后是他们已经购买的所有交易的总和(价格附在交易中) ,而不是PurchasedDeal)。
当然,我可以从所有用户的列表开始,包括交易和购买的交易。我已经尝试过,查询量很大(30,000个用户,提供或接受,3,000笔交易,100,000多笔购买交易)。
我可以从用户开始,然后做一个.each并找到已购买交易的那些,将它们分成他们自己的组,然后迭代每个那些以获得总数购买金额,但这是相当多的查询。
目前,这两种方法都需要很长时间才能超时。获得我需要的数据最有效的方法是什么?向表中添加列是完全可以接受的解决方案,顺便说一下。我有完整的数据库访问权限来完成我需要的工作。
谢谢!
答案 0 :(得分:0)
假设您向purchase_deals表添加价格列,您可以获得用户信息和总交易价格,如下所示:
select users.id, sum(purchased_deals.price) from users, purchased_deals where users.id = purchased_deals.user_id group by users.id having sum(purchased_deals.price) > 0
答案 1 :(得分:0)
要获取具有多个购买的用户ID列表,您可以执行以下操作,这将只访问一个表:
user_ids = PurchasedDeal.count(:group => :user_id, :having => 'count_all > 0').keys
随后,您可以使用以下命令获取所有这些用户:
users = User.find user_ids
可以通过计数器缓存加快速度。在您的用户模型中,将选项:counter_cache => true
添加到已购买交易的has_many
关联中。您需要在users表上添加一个额外的整数列并进行初始化,在迁移中可能如下所示:
add_column :users, :purchased_deals_count, :integer, :null => false, :default => 0
User.each { |u| User.reset_counters u, :purchased_deals }
一旦这样做了,就会变得简单得多:
users = User.all :conditions => 'purchased_deals_count > 0'
Rails将使您的列保持最新状态,并进行大多数标准操作。
要获得总价格将始终涉及加入。或者你可以建立一个交易价格的哈希值,并在Ruby中进行繁琐的处理。我不是SQL专家,但您可以通过使用PurchasedDeal存储价格来摆脱加入。否则,以下是使用连接的方法:
user_id_to_price = PurchasedDeal.sum 'deal.price', :include => :deal, :group => :user_id
您可以通过添加:conditions => ['user_id IN (?)', users]
之类的内容对您想要的用户进行过滤。 (其中users
可以是ID列表,也可以是用户对象。)