[Awesome Ruby Gem] Use bullet gem to help to kill N+1 queries and unused eager loading
bullet
The Bullet gem is designed to help you increase your application’s performance by reducing the number of queries it makes. It will watch your queries while you develop your application and notify you when you should add eager loading (N+1 queries), when you’re using eager loading that isn’t necessary and when you should use counter cache.
Best practice is to use Bullet in development mode or custom mode (staging, profile, etc.). The last thing you want is your clients getting alerts about how lazy you are.
Installation
You can install it as a gem:
1 | gem install bullet |
or add it into a Gemfile (Bundler):
1 | # Gemfile |
Then, run bundle install
.
1 | bundle install |
Configuration
Enable the Bullet gem with generate command
1 | bundle exec rails g bullet:install |
The generate command will auto generate the default configuration and may ask to include in the test environment as well. See below for custom configuration.
Note: make sure bullet
gem is added after activerecord
(rails) and mongoid
.
Bullet won’t do ANYTHING unless you tell it to explicitly. Append to config/environments/development.rb
initializer with the following code:
1 | config.after_initialize do |
Bullet also allows you to disable any of its detectors.
1 | # Each of these settings defaults to true |
Whitelist
Sometimes Bullet may notify you of query problems you don’t care to fix, or which come from outside your code. You can whitelist these to ignore them:
1 | Bullet.add_whitelist :type => :n_plus_one_query, :class_name => "Post", :association => :comments |
If you want to skip bullet in some specific controller actions, you can do like
1 | class ApplicationController < ActionController::Base |
Log
The Bullet log log/bullet.log
will look something like this:
N+1 Query:
1 | 2009-08-25 20:40:17[INFO] N+1 Query: PATH_INFO: /posts; model: Post => associations: [comments]· |
The first two lines are notifications that N+1 queries have been encountered. The remaining lines are stack traces so you can find exactly where the queries were invoked in your code, and fix them.
Unused eager loading:
1 | 2009-08-25 20:53:56[INFO] Unused eager loadings: PATH_INFO: /posts; model: Post => associations: [comments]· |
These two lines are notifications that unused eager loadings have been encountered.
Need counter cache:
1 | 2009-09-11 09:46:50[INFO] Need Counter Cache |
Advanced
Work with ActiveJob
Include Bullet::ActiveJob
in your ApplicationJob
.
1 | class ApplicationJob < ActiveJob::Base |
Work with other background job solution
Use the Bullet.profile
method.
1 | class ApplicationJob < ActiveJob::Base |
Run in tests
First you need to enable Bullet in test environment.
1 | # config/environments/test.rb |
Then wrap each test in Bullet api.
1 | # spec/rails_helper.rb |
Demo
Bullet is designed to function as you browse through your application in development. To see it in action, you can visit flyerhzm/bullet_test - https://github.com/flyerhzm/bullet_test or follow these steps to create, detect, and fix example query problems.
See Demo | flyerhzm/bullet: help to kill N+1 queries and unused eager loading - https://github.com/flyerhzm/bullet#demo to learn more.
References
[2] bullet | RubyGems.org | your community gem host - https://rubygems.org/gems/bullet