How to use ActiveRecord eager loading to raise your blood pressure
September 29, 2006 16:18 (Sydney Australia), updated about 18 hours later
Cameron and I’s little baby Web Connections had major problems the past few days. Heart wrenching for Cam, as he was responsible for the design and front-end, and I was responsible for the back end, and it all fell down on the day of the conference.
Originally I thought it was a server problem… the rails server process was growing to many gigabytes in a matter of minutes, and the server had gone down the night before.
It turned out not only was it my app’s problem, but my app probably took down the entire shared server the night before as well.
For some reason I took waaay too long to track it down, but finally, and with help from Jeremy at SegPub, I found it was in fact Cam’s profile page that was killing it.
Why was Cam’s profile killing it? Well, let’s have a look at the PeopleController#show action:
def show
@person = Person.find(params[:id], :include => [:photo, { :taggings => [:tag, :tagger] }, {:outgoing_relationships => :related_person}, {:incoming_relationships => :person}])
respond_to do |format|
format.html {
if logged_in?
@relationship_to = current_person.outgoing_relationships.to(@person)
end
}
format.xml {
render_xml @person.to_xml(:include => [:tags,
:outgoing_relationships,
:incoming_relationships,
:photo])
}
format.js {
render_json @person.to_json
}
end
end
Now I thought I was being super-tricky with that massive :include statement, making the profile page only perform one SQL statement to fetch all the required data.
It turns out that it was being a little too-tricky… the SQL statement ended up so large that it freaked out the database connection and the Rails app just blew up, taking the whole server with it.
Lesson learnt? Multiple SQL statements are OK. Check your eager loading in ActiveRecord and think about how it’ll scale.
Changing the code to a simple:
@person = Person.find(params[:id])
fixed everything, and it’s now ticking along smoothly again.

Comments
Andrew Krespanis
Ha! Cam’s fault, Cam’s fault, nah nah nee nah nah. ;)
AkitaOnRails
Well, A lot of outer joins can really freak out a query, but on the other hand I don’t know how much data you have.
Did you certify that your tables are all correctly indexed in the first place? Mainly in the foreign key columns? This should speed up things considerably.
Tim Lucas
Akita: Yep the tables are indexed correctly, it’s just that the query that the eager includes was generating SQL larger than MySQL’s query buffer
Sam Saffron
FWIW ,
I added my 2 cents on this at my blog
The way ActiveRecord implements eager loading is wrong.
To comment on this article you must have javascript enabled.