Railsのパフォーマンス改善方法

Railsは生産性の高いフレームワークですが、規模が大きくなるとパフォーマンスが課題になることがあります。 ページの表示速度やAPIレスポンスの遅さはユーザー体験に直結するため、改善方法を理解しておくことが重要です。 この記事では、Railsのパフォーマンス改善のポイントを整理し、実務で使える具体的な手法を紹介します。

#1. N+1問題の解消

問題例

# users/index.html.erb <% @users.each do |user| %> <%= user.profile.bio %> <% end %>
  • この場合、user.profile の取得でユーザーごとにSQLが発行される → N+1問題

改善方法

@users = User.includes(:profile).all
  • includes を使って関連データをまとめて取得
  • SQL発行回数を大幅に削減

💡 ポイント

  • N+1はRailsアプリの典型的なボトルネック
  • Bullet gemを使うと検知が簡単

#2. クエリ最適化

  • 不要なカラムを取得しない
User.select(:id, :name) # 全カラム取得は避ける
  • where句で絞り込みを行う
User.where(active: true)
  • 複雑な計算はDB側で処理
# Rails側で計算(非推奨) users.sum { |u| u.orders.count } # SQLで集計(推奨) User.joins(:orders).group(:id).count

💡 ポイント

  • DBへの負荷を減らす → Rails側での処理は最小限に

#3. キャッシュの活用

3-1. ページキャッシュ

# controller caches_page :index
  • 静的ページのレンダリングを減らせる

3-2. フラグメントキャッシュ

<% cache @user do %> <%= render @user %> <% end %>
  • 部分的に更新されない箇所をキャッシュする

3-3. Rails.cache

Rails.cache.fetch("popular_articles", expires_in: 1.hour) do Article.popular.to_a end
  • 計算コストの高い処理結果をキャッシュ

💡 ポイント

  • キャッシュは更新タイミングを意識して使う
  • Redisなど高速ストレージとの組み合わせが一般的

#4. インデックスの追加

  • DBクエリ速度改善の基本
add_index :users, :email, unique: true add_index :orders, [:user_id, :created_at]
  • 外部キーや検索に頻繁に使うカラムには必ずインデックスを追加

💡 ポイント

  • インデックスは追加しすぎても書き込み性能に影響するため、必要箇所だけに

#5. バッチ処理の導入

  • 重い処理は非同期で行う
# ActiveJob class SendNewsletterJob < ApplicationJob queue_as :default def perform(user_id) user = User.find(user_id) NewsletterMailer.send_newsletter(user).deliver_now end end
  • SidekiqやResqueと組み合わせることでレスポンスを高速化

💡 ポイント

  • Webリクエスト中に重い処理を行わない

#6. ペジネーションの利用

  • 大量データを表示する場合は必ずページング
@users = User.page(params[:page]).per(20)
  • kaminariやwill_paginateが便利

💡 ポイント

  • 一度に全件読み込まない → メモリとDB負荷を削減

#7. その他の改善ポイント

改善項目内容
メモ化memoize を使い、同じ処理を繰り返さない
プリロードincludeseager_load で関連データを事前取得
SQLの見直しEXPLAINでクエリプランを確認
ログレベル調整productionで log_level = :info などにする
Webサーバ調整PumaやUnicornのスレッド数・ワーカー数を最適化

#8. まとめ

Railsのパフォーマンス改善は DBアクセスの最適化 + キャッシュ + 非同期処理 が基本です。

  • N+1問題をなくす → includes / eager_load
  • DBクエリを最小化 → select / where / インデックス
  • キャッシュ活用 → Rails.cache / フラグメント / ページキャッシュ
  • 重い処理は非同期 → ActiveJob / Sidekiq
  • 大量データはページング

💡 ポイント

  • まずはボトルネックの特定から
  • New RelicやBulletなどのツールで計測 → 改善箇所を見極める

タグ一覧