RailsでSlow Queryを自動検出する方法
開発が落ち着いてくると新規開発みたいな慌ただしさが減り、使い勝手を向上させるため、SQLのチューニングをする必要が発生します。
いわゆる保守フェーズになります。
その際に、sloq queryを自動的に検出できたら、より効率的になるのですがRailsだとかなり簡単だったのでご紹介します。
SQLの改善はやり方によって、1000倍ぐらいパフォーマンスが変わり、SEOの改善が起きたりとても良いのでぜひいろんなサービスに入れて良いサービスなると良いですね。
設定方法
簡単です。initializerでActiveSupport::Notifications
を使ってsql.active_record
をsubscribeするだけでした。
# config/initializers/slow_query_logger.rb class SlowQueryLogger def self.initialize! ActiveSupport::Notifications.subscribe('sql.active_record') do |_name, start, finish, id, payload| duration = finish.to_f - start.to_f Rails.logger.debug("slow query detected: #{payload[:sql]}, duration: #{duration}") end end end SlowQueryLogger.initialize!
initializerにコードを書き、railsを再度起動してみると development.logには slow query detected
とでるようになります。
slow query detected: SELECT `messages`.* FROM `messages` WHERE `messages`.`user_id` = 5 AND `messages`.`id` = 13 ORDER BY FIELD(messages.id, 13), duration: 0.004096031188964844
試しに表示しただけなので、実際に使えるコードはこんな感じになります。 3秒以上のqueryを検出してくれます。簡単ですね。
# config/initializers/slow_query_logger.rb class SlowQueryLogger MAX_DURATION = 3.0 def self.initialize! ActiveSupport::Notifications.subscribe('sql.active_record') do |_name, start, finish, id, payload| duration = finish.to_f - start.to_f if duration >= MAX_DURATION Rails.logger.debug("slow query detected: #{payload[:sql]}, duration: #{duration}") end end end end SlowQueryLogger.initialize!
他にもrender時間の計測や特定のメール送信をフックしてslackに通知させたりできます。