Load IDs For Limited Eager Loading

Hi

Trying to cut down on queries with eager loading and noticed the
following in development.log

Load IDs For Limited Eager Loading - SELECT id …etc

Followed by

Load Including Associations - SELECT table.id … etc

Is this common practice? What is limted eager loading?

Cheers

Mark

If you do something like Person.find(:all, :include => :notes, :limit
=> 10) AR requires two queries to get the result.

The first query just queries the people table and stores the 10 id
numbers that are to be loaded.

The second query queries the people and notes tables and adds a
condition that the id is included in the list of 10 stored ids.

Doing it all at once would not work because as well as a row for each
row in the people table, extra rows are included because of the left
outer join used on the notes table. For example, if the first person
had 10 notes associated with them, the limit would take those 10 rows
and you’d end up with a result that had 1 Person with their notes
preloaded. Not what you expect. You expect the :limit => 10 to give
you 10 Person objects.

To do it in one query you’d have to use a subselect in a condition of
the query. Some databases don’t support subselects.

select * from people left outer join notes on people.id =
notes.person_id where people.id in (select id from people limit 10)

Clear as mud? :slight_smile:

-Jonathan.

Thanks Jonathan

You were right - clear as mud :wink:

As a general rule of thumb should I use :limit wherever possible even if
I am creating a second query with eager loading or does it depend on my
data?

Cheers

Mark

Two queries are only necessary if you use :limit and :include
together. If you plan to use all the included associations then don’t
worry about the second query, it’s still faster than not including
them.

Using :limit is good because you are reducing the number of AR objects
that have to be instantiated.

-Jonathan.

Thanks for your knowledge on this.

Enjoy your day.

Cheers

Mark