Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[guides] 4.2 release notes: added technical details for Adequate Record #16844

Merged
merged 1 commit into from
Sep 16, 2014

Conversation

zerothabhishek
Copy link
Contributor

Please review the changes as this is my first PR.
Edit:
Here's the added text for quick reference (second paragraph onwards):
Added text is in the comment below

Adequate Record

Rails 4.2 comes with a performance improvement feature called Adequate Record
for Active Record. A lot of common queries are now up to twice as fast in Rails
4.2!

This feature caches SQL query patterns while executing some activerecord query methods. Activerecord queries are transformed into SQL before being executed, and this cache helps skip some computation involved in the transformation. More details in Aaron Patterson's post.

It affects the find and find_by query methods and association queries.

The following call will cache the resultant query pattern, such that the next time there is a similar call, the pattern is re-used

Post.find 1

# Cached query pattern: 
# SELECT  posts.* FROM posts WHERE posts.id = ? LIMIT 1

Post.find 2  # uses the Cached pattern

Similarly for find_by:

Post.find_by_title 'first post'
# OR
Post.find_by title: 'first post'

# Cached query pattern:
# SELECT  posts.* FROM posts WHERE posts.title = ? LIMIT 1

Post.find_by_title 'second post'  # uses the Cached pattern

This cache is sometimes called the AST-cache (where AST is abstract syntax tree)

Here are some scenarios where the cache is not used -

  • find with a list of ids. eg- Post.find(1,2,3) or Post.find([1,2]).
  • find_by with a non hash argument. eg- Post.find_by "published_at < ?", 2.weeks.ago.
  • The model has a default scope.
  • The model uses single table inheritence to inherit from another model.

Association queries too use a similar AST-cache. This cache is different from the association caching that already existed in Rails. For example

post = Post.find 1
post.comments  # Comment objects cached, query pattern cached

So the next time we invoke the comments method, we get the objects from the association cache. But if we force the query to get a refresh the comments, the AST-cache will be used:

post.comments       # SQL not fired, association cache used
# => #<ActiveRecord::Associations::CollectionProxy ... >
post.comments(true)  # SQL forced, AST-cache used

@@ -56,7 +56,59 @@ Rails 4.2 comes with a performance improvement feature called Adequate Record
for Active Record. A lot of common queries are now up to twice as fast in Rails
4.2!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should improve this paragraph a little bit too, a few issues with it:

  • This is not so much of a "feature"... in the sense that it doesn't have a public interface and you don't need to do anything special to benefit from it, so it's more like a "refactor", or perhaps a "performance improvement"?
  • "called Adequate Record" – you won't find that term anywhere in the code or in the documentation, so perhaps we should say something along that lines of "codenamed Adequate Record" instead.
  • Nit: ending with a "!" seems a little bit too "exciting" for formal documentation? 😄

@chancancode
Copy link
Member

First of all, thank you so much for working on this! ❤️

Overall, I think this seems a little bit too detailed. I suggest that you take some inspiration from the Rails 4.1 release notes for the level of details.

Upon reading those, it seems like they tend to follow the pattern of (what problem does it solve) + (how does it work) + (how would you use it) + (some caveats), which adds up to ~4 short paragraphs (2-3 sentences each). We should probably adopt that basic model here 👍

Specifically:

  1. What problem does it solve? Make common queries faster? Cache the computation?
  2. How does it work? We should leave the juicy details to Aaron's blog post 😄 If you look at the bullet point for Spring in 4.1, it merely says "It speeds up development by keeping your application running in the background so you don't need to boot it every time you run a test, rake task or migration." which is probably the level of details that most users would care to understand (and the rest can click through to the blog post).
  3. How do you use it? This is interesting, because you don't actually have to do anything to benefit from this 😄 However, it is worth mention here what would benefit from this improvement in bullet points form.
  4. Some caveats Does this work with DBs that doesn't support prepared statements? (Yes.) Which calls won't benefit from this?

This is just a rough guideline of course 😄 For example, perhaps it makes sense to mention everything about the common find* queries and then mention the associations stuff at the end. There are probably other ways to structure this too, I'll leave it to you to explore – just remember the goal is to help the audience quickly answer those high-level questions quickly.

Does it make sense? 😁

@zerothabhishek
Copy link
Contributor Author

Thanks for the detailed feedback @chancancode.
I too felt this was getting far too detailed for release notes. But because there are so few details outside of Aaron's post, especially on the caveats, I felt it was important to put them up somewhere.
The four part pattern you suggest looks just the right size to cover them, so I'll use it to rewrite. Thanks again :)

Here are some scenarios where the cache is not used -

- `find` with a list of ids. eg- `Post.find(1,2,3)` or `Post.find([1,2])`.
- `find_by` with a non hash argument. eg- `Post.find_by "published_at < ?", 2.weeks.ago`.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this specifically for SQL fragments? (that might be more obvious phrase for people than 'non-hash argument')

@zerothabhishek
Copy link
Contributor Author

Edited based on comments by @chancancode.
@GeekOnCoffee Changed the line to use sql fragments as you suggested.

Here's the new text:

AdequateRecord is a set of refactorings that make ActiveRecord find and find_by methods and some association queries upto 2x faster.

It works by caching SQL query patterns while executing the Activerecord calls. The cache helps skip parts of the computation involved in the transformation of the calls into SQL queries. More details in Aaron Patterson's post.

Nothing special has to be done to activate this feature. Most find and find_by calls and association queries will use it automatically. Examples -

Post.find 1  # caches query pattern
Post.find 2  # uses the cached pattern

Post.find_by_title 'first post'  # caches query pattern
Post.find_by_title 'second post' # uses the cached pattern

post.comments        # caches query pattern
post.comments(true)  # uses cached pattern

The caching is not used in the following scenarios -

  • The model has a default scope

  • The model uses single table inheritence to inherit from another model

  • find with a list of ids. eg-

    Post.find(1,2,3)
    OR
    Post.find [1,2]
  • find_by with sql fragments.

    Post.find_by "published_at < ?", 2.weeks.ago

@seuros seuros added this to the 4.2.0 milestone Sep 14, 2014
@seuros seuros added the docs label Sep 14, 2014
Rails 4.2 comes with a performance improvement feature called Adequate Record
for Active Record. A lot of common queries are now up to twice as fast in Rails
4.2!
AdequateRecord is a set of refactorings that make ActiveRecord `find` and `find_by` methods and some association queries upto 2x faster.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adequate Record and Active Record. We only use them in camel case when we are talking about the constants.

@zerothabhishek
Copy link
Contributor Author

Edited after @rafaelfranca's comments.

rafaelfranca added a commit that referenced this pull request Sep 16, 2014
[guides] 4.2 release notes: added technical details for Adequate Record
@rafaelfranca rafaelfranca merged commit de33fe7 into rails:master Sep 16, 2014
@rafaelfranca
Copy link
Member

❤️ 💚 💙 💛 💜

@zerothabhishek
Copy link
Contributor Author

Thanks @chancancode, @GeekOnCoffee, @rafaelfranca, you guys rock 🤘 🌟 ✨
First commit to Rails yay! 😂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants