我有很多重复的记录,我正在努力剔除,为了做到这一点,我目前正在运行:
Survey.active.each do |survey|
survey.response_sets.completed.each do |set|
answer_ids = []
set.responses.each do |r|
if r.answer.blank?
r.destroy
else
if answer_ids.include? r.answer_id
r.destroy
else
answer_ids << r.answer_id
end
end
end
end
end
它查找所有活动调查,获取每个调查的响应集,然后获取每个响应集的单个响应。
然后根据响应集中的另一个响应是否存在
answer_id
来查看响应是否重复。在给定的响应集中,对于给定的answer_id
,只能有一个响应。所以,如果有副本,它会销毁副本。超过几十万排,进展非常缓慢。
那么,我怎样才能加快这个过程呢?
下面是对其中每一个的sql调用:
Survey.active
SELECT "surveys".* FROM "surveys" WHERE "surveys"."active" = 't'
survey.response_sets.completed
SELECT "response_sets".* FROM "response_sets" WHERE ("response_sets".survey_id = 12345) AND (completed_at IS NOT NULL)
set.responses
SELECT "responses".* FROM "responses" WHERE ("responses".response_set_id = 54321)
我正在运行Rails3.0.6和PostgreSQL。
最佳答案
我想你可能是从错误的角度来攻击这件事。首先,您不应该允许坏数据进入数据库。我真的看不到数据库模型的样子,但是模型中的一些验证可能会阻止您这样清理数据库。在rails中加载非常大的数据集是一件痛苦的事情,而且它非常慢,而且内存也非常匮乏。
# maybe something like this?
class Responses < ActiveRecord::Base
validates_uniqueness_of :answer_id, :scope => :id
end
批处理提示(添加)
activerecord在处理大型结果集时并不能很好地工作。如果您有will_paginate或类似的东西,您可以很容易地在完整的数据集中分段循环。
(1..Survey.total_pages).each do |p|
Survey.paginate(:page => p, :per_page => 30).each do |survey|
# your loop but with less memory overhead
关于sql - 我如何加快这段代码的速度?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8807499/