Ruby on Rails development from scratch (59)-ActiveRecord base (preload child records)

Source: Internet
Author: User
Tags comments memory usage table name server memory ruby on rails

Pre-loading child records discuss issues that are the same as "deferred loading." Usually active records postpone loading child records from the database until you need them, for example, through the example in RDoc, we assume that the blog program has a model, as follows:

Class Post < activerecord::base
Belongs_to:author
has_many:comments: Order => ' created_on DESC '
End

If we iterate through all of the posts, access the author and comment properties, we use an SQL query to return multiple records in the posts table, and for each post record, SQL is executed once to access the authors table and comments table, which is 2n+1 times.

For post in Post.find (: All)
puts ' post: #{post.title} '
puts ' written by: #{post.author.name} '
puts ' last Comment on: #{post.comments.first.created_on} ' End

There is a serious performance problem with the code above, and we can fix it by using the Find method's include parameter, which lists the associations that require deferred loading when the found method is executed. An Active record would be smart enough to load data one at a time, and if there were 100 posts, the following code would eliminate 100 database queries compared to the above code:

For post in Post.find (: All,: include =>: author)
puts "post: #{post.title}"
puts "written by: #{post.author. Name} '
puts ' last comment on: #{post.comments.first.created_on} '
end

This example can also be simpler, using only one sql:

For post in Post.find (: All,: Include => [: Author,: comments])
puts "post: #{post.title}"
puts "written by: #{po St.author.name} "
puts" last comment in: #{post.comments.first.created_on} "
end

Pre-loading child records do not guarantee improved performance (in fact, if your database does not support left-side connections, then you cannot use deferred loading, and if you are using Oracle8, you must upgrade to ORACLE9), because preload adds all the tables in SQL. This will have a lot of records to be loaded and converted into the Model class objects, this can lead to problems with memory usage, especially when a record has a lot of note records, which is more pronounced, and the preload consumes more server memory than a bunch of deferred load child records.

If you use: include, you need to use the Find method parameters to eliminate the ambiguity of the column name, add the table name before the column name to distinguish, in the following example, the title column needs to add a table name prefix:

For post in Post.find (: All,: Conditions => "posts.title like '%ruby% '",
: Include => [: Author,: comment])
#. ..
End
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.