Eager Loading

June 15, 2007 at 7:42 pm Leave a comment

I have an unusual Rails application. This web app has about 1000+ rows of data that it loads each time someone hits the main page. This is pretty much the entire database. It takes around 9 seconds to load this data and draw the page, about 2 seconds of that is database access (about 400 SQL queries). Fortunately, this isn’t a public web app, as those load times would kill it.

I recently read about eager loading, a Rails feature that loads your data in with a single database call. The default database method Rails uses is to only pull data as it is needed. So, as you actually start using the data, it then performs the database queries to grab it. This is normally for the best so you don’t waste time loading data that you don’t even use. With this particular web application, the entire database is brought up when you hit the main page of this site, so eager loading seemed to make sense.

(Note: For those of you worried about the users of this app, most operations that they need to perform are done using AJAX after the initial page load, so the users aren’t suffering needlessly.)

Here’s the data model I’m using (though I’ve pulled the validation related code):

class CoreRouter < ActiveRecord::Base
has_many :ports

class Port < ActiveRecord::Base
belongs_to :core_router
has_many :addresses

class Address < ActiveRecord::Base
belongs_to :port

My first attempt at eager loading:
@core_routers = CoreRouter.find(:all, :include => [ :ports, :addresses])

But that fails:

ActiveRecord::ConfigurationError (Association named ‘addresses’ was not
found; perhaps you misspelled it?):

After a bit of thought, it makes sense. The CoreRouter class doesn’t have a direct association with the Address class, so it doesn’t know how to associate the data.

Fortunately, you can nest this:

@core_routers = CoreRouter.find(:all, :include => {:ports => :addresses})

This essentially joins the Ports table with the Addresses table, then joins that result to the CoreRouter table.

That shaved the time for SQL on this web app from about 2 seconds to less than 0.5 seconds.

Now, I just have to find the time to go back and rewrite the code that takes about 6 seconds to format the data for the website…


Entry filed under: Ruby.

WPA Enterprise security non-IT related (Honeywell Thermostat)

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

Trackback this post  |  Subscribe to the comments via RSS Feed


June 2007
« May   Jul »

Most Recent Posts

%d bloggers like this: