我有很多重复的记录,我正在尝试清除它们,为此,我当前正在运行以下命令:
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)
我正在运行 Rails 3.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/