Friday 22 May 2015

Speed up Active record With inclulde method.

When you’re building a new Rails app, ActiveRecord’s defaults will take you far. Querying with .where, inserting with .save — it’s all so easy, and it’s fast enough.
But after a while — when a page of mostly simple content takes a second or more to come back from the server, when you start seeing 504 Gateway Timeout errors coming back from nginx because it’s taking too long to process the CSV you uploaded — that’s when you know you’re going to have to spend some time on performance.
You could solve a lot of these problems with caching. But that adds a whole extra layer of complication. Between expiration, nesting partials, and bugs that only reproduce in production, it’s a headache you don’t need right now.
Instead, you can spend some time fixing the most common performance problem I’ve seen in Rails apps: hitting your database too much.
Even if you’re running the database on the same machine, there’s a lot of connection overhead that’ll slow you down. And if your database is on another machine, fetching data that often will just destroy you.
But you don’t have to go too far from the simplicity of Rails to see drastic improvements in your app’s response time.

You’re trying to find ten restaurants along with with their reviews, and you’re doing eleven SQL calls!

This is called the “N+1 query problem”: for every restaurant, you’re doing one query for the restaurant data, plus one query for each of their associated reviews. You can probably imagine how bad it becomes the deeper you go. Imagine if you also wanted to grab each restaurant’s address, as well as each address’ phone number.
You’ll run into this problem when you loop over a list of objects and try to query their associations:

app/views/restaurants/index.html.erb
<% @restaurants.each do |restaurant| %>
  <tr>
    <td><%= restaurant.name %></td>
    <td><%= restaurant.review_average %></td>
    ...
 
You don’t need to hit the database N+1 times. You want to hit it at most twice: once for the restaurants you’re trying to find, and once for all of the reviews associated with all of those restaurants.
This is called “eager loading,” and you can do it really easily with .includes:

app/controllers/restaurants_controller.rb

def index
  @restaurants = Restaurant.all.includes(:reviews)
end
 
Or, if you want to do something more complicated, like preload all the addresses and the reviews’ authors:

app/controllers/restaurants_controller.rb
def index
  @restaurants = Restaurant.all.includes([{:reviews => author}, :address])  
end

Or, if you want to do something more complicated, like preload all the addresses and the reviews’ authors:

app/controllers/restaurants_controller.rb
def index
  @restaurants = Restaurant.all.includes([{:reviews => author}, :address])
end
You have to specify the associations you want to preload, using that array and hash syntax. Rails will do the best it can at consolidating down those calls:

For more Click

 

 

No comments:

Salesforce CRM vs. Zoho: A Comparative Analysis

Introduction: Selecting the right customer relationship management (CRM) software is crucial for businesses seeking to streamline their sal...