Here are some interesting tips to optimize Queries in rails using Bullet.
The traditional method (sans the optimization)
This is the old fashioned method of optimization which was initially used by bullet. This example shows two models; Order and Product, wherein an Order consists of many Products. The code script should be:
class OrdersController < ApplicationController
@orders = Order.all
<% @orders.each do |order| %>
<h2><%=link_to order.title, order_path(order)%></h2>
<%order.products.each do |product|%>
<li><%=link_to product.title, product_path(product)%></li>
<% end %>
Source - http://blog.andolasoft.com/2013/05/3-easy-steps-to-optimize-queries-in-rails-using-bullet.html#
This script would however generate some N+1 query issues, the reason being that we have set the query just once in order to get the orders and then separate each query to fetch the products. These are also the kinds of problems that are quite frequently and easily overlooked by programmers. Also, this is where the “Bullet” gem helps in avoiding the issues.
The gem “Bullet” can be integrated to the query in just three easy steps.
Add “Bullet” get to the Gemfile
gem 'bullet', '4.6.0', :group => “development”
Run the “bundle install” to install the gem “bullet” in development group
Optimize the configuration setting in the development.rb file
For slowing the “bullet” to change its configuration using the after_initialize block contained in the development.rb file. Set the alert as “true” to get the alarms via the browser.
Bullet.enable = true
Bullet.alert = true
Bullet.bullet_logger = true
Bullet.console = true
Bullet.rails_logger = true
Restarting the server
The N+1 query can be simultaneously fixed using the following steps:
lass OrdersController < ApplicationController
@orders = Order.includes(:products)
After you have changed the statement from “Order all” to “Order.includes’ (:products), you need to call eager loading to fetch the products. The date herein would be fetched using two queries, one to obtain the orders and the other to retrieve the products in the orders.
The gem “bullet” can also point out when we are unnecessarily eager loading.
Benefits of optimization
- No need to search each line of code to figure out inefficiency in database query
- Automatic notification / alert messages
- Prevent inefficient database query like N+1
- Detect unused eager loading