12/08/2018, 13:50

Check N+1 query dùng gem bullet

Cài đặt gem Thêm dòng sau vào Gemfile gem "bullet" Sau đó gõ trong console bundle install Thêm đoạn mã sau vào config/environments/development.rb config.after_initialize do Bullet.enable = true Bullet.alert = true Bullet.bullet_logger = true Bullet.console = true ...

Cài đặt gem

Thêm dòng sau vào Gemfile

gem "bullet"

Sau đó gõ trong console

bundle install

Thêm đoạn mã sau vào config/environments/development.rb

config.after_initialize do
  Bullet.enable = true
  Bullet.alert = true
  Bullet.bullet_logger = true
  Bullet.console = true
  Bullet.rails_logger = true
  Bullet.add_footer = true
end

Chạy server sau đó vào từng trang một, nếu thấy có thông báo như sau thì bạn đã bị N+1 query. Dưới bottom cũng hiện như vậy:

log.jpg

Trong thông báo đó cũng đã hướng dẫn mình cần làm gì, ở dòng bao nhiêu, như ví dụ trên ta có ở file _user_subject.html.erb.2 -> dòng 2.

Dưới bottom cũng sẽ hiển thị mình cần làm gì:

user: xoan N+1 Query detected UserSubject => [:user] Add to your finder: :includes => [:user]

-> Cần thêm .includes(:user) vào biến trong dòng đó. Ví dụ code của mình là:

@course = Course.includes(course_subjects: :user_subjects)
  .find params[:course_id]

Ở hàm show của user_subject, mình có gọi user_subject.user -> bị N+1 query ở đó -> trong code kia của mình sẽ phải sửa như sau:

@course = Course.includes(course_subjects: [user_subjects: :user])
  .find params[:course_id]

Trường hợp bị thừa sẽ có thông báo: log.jpg

Vì mình đã includes thừa:

@course = Course.includes(course_subjects: [:subject, user_subjects: :user])
  .find params[:course_id]

-> Sửa lại như sau:

    @course = Course.includes(course_subjects: [user_subjects: :user])
  .find params[:course_id]

Cũng có thể sẽ thông báo như vậy nhưng các bạn cần includes trong view tùy vào các trường hợp. Cảm ơn các bạn đã xem.

0