On Sep 19, 2008, at 6:55 PM, Pardee, Roy wrote:
> I may not understand your second thought, but I have a hard time  
> imagining it will be faster than the loop over all records in your  
> first thought.  Since you've got to retrieve the record & make it an  
> AR instance in any case, you may as well not mess around guessing  
> IDs...
>
> Are you sure you can't translate your ruby function to SQL?  That's  
> going to be loads faster...  Can you break your records up into  
> chunks that should all get the same value of my_field & do a series  
> of subset UPDATEs maybe?
>
> -----Original Message-----
> From: [email protected] 
> [mailto:[email protected] 
> ] On Behalf Of JimCifarelli
> Sent: Friday, September 19, 2008 2:28 PM
> To: Ruby on Rails: Talk
> Subject: [Rails] Updating a Field in All Records of a Model,  
> Efficiently?
>
> Hello Everyone,
>
> I have a Model for which there are many thousands (hundreds of
> thousands) of records.  I'd like to update the value of one field  
> for each record in a rake task.
>
> A ruby based function must be applied to this field for all records  
> (i.e. can't perform the algorithm in an SQL UPDATE alone).
>
> First Thought:
> MyModel.find(:all).each { |m| m.my_field = function_call_here;  
> m.save } Load all the models into memory, and I'd like to avoid that.
>
> Second Thought:
> Get the maximum "id" of the Model's records and program a loop,  
> doing a "find_by_id" for each record.
> While the model does have an "id" field, some records have been  
> deleted, so I would have to check that the "find_by_id" is nil...
>
> I'm not worried about new records being added to the database as  
> this update will be run during a "maintenance" period.
>
> Anyone have any thoughts on how you would update every record for a  
> model when you have a large number of records?
>
> Thank you for your time and help.
>
> -Jim


Jim,

When I've had to do a similar thing over a table with
many (100,000+) records, I've done something like:

total = Model.count
limit = [ 100, total ].min
0.step(total-1, limit) do |offset|
   Model.find(:all, :limit => limit, :offset => offset).each do |model|
     # do stuff
   end
end

If you have a condition that limits what comes back, you might have to
tweak the offset if the "stuff" you do causes records to fall out of
the condition.

Roy's idea of a series of Model.update_all() calls for each unique set
of whatever goes into your function sounds like a winner if the
function is predictable enough.

-Rob


Rob Biedenharn          http://agileconsultingllc.com
[EMAIL PROTECTED]


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to