Learned: ActiveRecord performance boost with find_by_sql or :select

December 04, 2007 · 1 comment

As mentioned in a previous post about url_for, sometimes Rails magic needs to be de-emphasized or eliminated to attain the performance you need.

Rails provides excellent statistics to help you see how your application is humming along.

While you can go into the depth with various tools, like wrapping Benchmark block around code to see how it performs, the hints about where to look are in the logs.

A sample action will generate the following information in the logs:

Completed in 1.77621 (0 reqs/sec) | Rendering: 0.10928 (6%) | DB: 0.50002 (28%)

The discrepancy between the completed, rendering and db times lets know that you have overhead hidden away in an action.

Unless you are doing serious processing, like generating a PDF or accessing a web service, there is an obvious place to start.

The objects you are retrieving with ActiveRecord.

Having had experience with Apple’s WebObjects, I was familiar with the overhead involved in retrieving and instantiating objects.

Instantiating is the key place to look first.

In my case, the performance issue only revealed itself when a customer using the page ended up with thousands of records, not tens or even hundreds.

This action was using a typical AR finder method, with conditions to affect the results based on user input.

In development mode I was able to view the query and craft a custom finder that relied on find_by_sql.

On top of that, I honed down the columns retrieved to the bare minimum.

By default, ActiveRecord retrieves all columns, which can add significantly to the overhead during instantiation.

You can go lower, by retrieving the values using the bare bones database connection.

In my case, that wasn’t needed - yet.

1 response so far ↓

  • 1 Chris Blow // Jan 28, 2008 at 02:01 AM

    Thanks for taking the time to write up your "learned" posts. I also just got bitten by unexpectedly large result sets eating incredible overhead during object instatiation, and it was good to hear your explanation if it w.r.t. the logger discrepancy. Benchmarking revealed my problem, but if I had been paying closer attention to my applog i would have seen the problem much sooner.

Leave a Comment