見出し画像

トラブル対応で学んだN+1問題

みなさんこんにちは。 株式会社キャリタス システム開発1部2課です。
今回はトラブル対応を通じて筆者が学んだことについて話せればと思います。


はじまり

ある時からwebサーバーで突発的にメモリの使用量が上昇してアラートがあがるようになりました。
急遽サーバーを強化し、いろいろと原因を調査した結果、開発ベンダーからRails特有の”N+1問題”が発生していそう。。と報告がありました。

1部2課の前回の記事でご紹介したとおり、我々はシステム開発マネジメントを主な業務としており、PMのプロフェッショナルはいますが、実際にコーディングを行っているわけではありません。
とくに筆者はエンジニア歴約3年目と経験が浅く、Ruby on Railsを触ったことが無いのでN+1問題とはなんぞや。。というのが正直なところでした。

N+1問題を学んだ

とはいえ、Rails特有の問題という話なので、調べると分かりやすい記事がたくさん出てきます。
いろんな記事を読んだ結果、筆者は以下のように概要を理解しました。


  • 本来であればまとめて1回でデータを取得できるはずなのに、書き方によっては簡単にN回の追加クエリが発行されてしまう現象。

  • 例えばユーザIDを取得する場合、まとめて取得できるはずが、ユーザの数だけIDを取得するクエリが発行されてしまう。など。

  • データベースへの問合せ回数が増えるので、処理するデータ量によってはメモリやCPUなどのサーバーリソースを食いつぶしパフォーマンスの低下を発生させる。

対策

N+1問題はコーディング次第で回避できる問題です。
今回はある画面で特定のデータを取得するにあたって、1件づつ取得するクエリを発行していたのですが、あるユーザではデータ量がかなり多かったため大量のクエリが発行されることになり、サーバーを強化しないといけないほどのパフォーマンス低下を発生させていました。

そこで対策として不必要な追加クエリが発生しないよう、関連データをまとめて1回のクエリで取得するようなSQLのチューニングを行いました。
これによりサーバー負荷も発生しなくなり問題は無事解決しました。

また、水平展開として現在パフォーマンスが悪いクエリがあるか調査し、同じ問題が他の場所で起こっていないか確認を行いました。

今後の課題

N+1問題の怖いところは、データ量によってはある時から急に問題が発生する場合がある、
つまり今はデータ量が少なく問題となっていないが、将来的にデータ量が増え問題化する可能性が潜在しているということです。

本来、設計やコーディングの段階で防ぐべき問題ですが、すでに紛れ込んでしまったものはプログラムを全て見直しチェックを行ったうえで、本当に問題ないか性能試験を実施するのが理想ですが、現実はそうも行きません。
我々はこの問題が潜在していることを常に頭に置いておき、N+1問題が発生した場合は意識して調査することで早期解決に導く必要があります。

終わりに

今回のできごとを通じて筆者が学んだ、N+1問題について記事にしてみました。
コーディングをしているわけではないので、概要レベルでの理解ではありますが、この問題が存在しているのを知ったことに意味があると思っています。

筆者はまだまだ経験が浅く試行錯誤の日々ですが、今後も知らない知識があれば勉強を怠らずに頑張っていきたいと思います。

最後まで読んで頂きありがとうございます!
今後も定期的に投稿しますので是非また読んで頂ければうれしいです!

我々は新卒、中途採用を実施しています。ご興味のある方は下記リンクよりご応募お願いします!


この記事が気に入ったらサポートをしてみませんか?