Article by: Sergiy Dybskiy
Shopify で働いていたとき、ブラックフライデーとサイバーマンデーはまさに私たちにとってのスーパーボウルでした。マーチャントの皆さんが1年の中で重要な時期に予期せぬトラブルに遭遇しないよう、数週間も前からコードフリーズに入っていました。それでも、ときには直前になってアップデートをリリースしなければならないこともあります。
たとえば、こんな場面です。
ブラックフライデー前夜の午後 11 時 47 分。50 点以上の商品を割引価格で掲載した新しい /sale ページをデプロイしたばかりです。マーケティングチームはこれから 50 万人の購読者にメールを送ろうとしています。サンプルデータでのテストはすべて問題ありませんでした。
そして午前 0 時 13 分、最初の Sentry アラートが届きます。

問題
/sale エンドポイントの平均レスポンスタイムが 1 リクエストあたり 4 秒以上かかっています。ユーザーはタイムアウトを経験しており、今すぐこの問題を修正する必要があります。

Sentry が問題を検知する
Sentry を開いてみると、すでに原因が特定されています。N+1 クエリです。Sentry はトランザクションスパンを自動的に解析し、/api/sale エンドポイントがリクエストごとに 150 回以上の連続したデータベースクエリを発行していることを突き止めました。

Issue の詳細を見ると、典型的なパターンが現れています。
まず最初に全商品を取得するクエリが 1 回実行され、その後に各商品のセール価格、メタデータ、カテゴリ情報を取得するクエリが何度も繰り返し実行されています。典型的な N+1 です。
こう実装したのは、そのほうがシンプルだったからです。まず全商品を取得し、そのあとループで各商品のセールデータを取得する。見た目にもコードはきれいで、テスト商品が 5 件のときには完璧に動いていました。
しかしセール対象商品が 50 件になるとどうでしょうか。1 ページのロードごとに 151 回のクエリが発行されることになります。
Using Seer
Sentry でこの Issue を開き、「Find Root Cause」をクリックします。
Seer はトレースデータとコードベースを解析し、その結果として Root Cause Analysis(根本原因分析)を提示します。


商品ループ内で順次実行されるデータベース呼び出しにより、N+3 クエリパターンが発生し、合計 54 件のクエリと 10 秒超のレイテンシが生じています。
Seer は問題のあるコードをピンポイントで特定します。

修正方法




違い
「何かおかしいぞ」から「修正をデプロイ完了」まで、全工程にかかった時間は 6 分でした。
- 自動検知(0 分):問題が発生した瞬間に、Sentry が N+1 Issue を検知
- 根本原因分析(2 分):Seer がトレースデータを解析し、問題の核心を特定
- 解決策の生成(1 分):Seer が適切な SQL JOIN を用いた、本番適用可能なコードを提案
- PR 作成とデプロイ(3 分):レビューしてマージし、リリース
Seer がなければ、トレースやログをひたすら追いかけるのに数時間はかかっていたはずです。しかもブラックフライデーのようなタイミングでは、あなたがデバッグに費やす 1 分は、そのままユーザーが待たされる 1 分になります。
Seer は単に問題を特定するだけではありません。パターンを説明し、どこで発生しているのかを正確に示し、本番環境で使えるコードを提示し、さらに PR まで作成します。
なぜ重要なのか
ブラックフライデーやサイバーマンデー、あるいは新製品のローンチ時など、デバッグに時間がかかることは大きなコストになります。
ユーザーが不具合を経験しているときには素早い回答が求められますが、Seer はその「答え」を提供することができます。パフォーマンスデータを解析し、問題を分かりやすく説明し、具体的な解決策を自動生成します。Sentry の自動 Issue 検出機能に、AI を活用した根本原因分析とコード生成を組み合わせたものが Seer です。
重要なタイミングでパフォーマンス問題に直面したとき、Sentry が検知し、Seer がその修正を手助けしてくれます。
ユーザーが気づく前に、N+1 問題を Seer がどう解決できるのか、ぜひ確認してみてください。Seer の詳細をチェックし、AI を活用したデバッグを始めましょう。
N+1 と Seer に関する FAQ
■N+1 クエリ問題とは具体的に何ですか?
N+1 クエリ問題は、コードが 1 回の「メイン」クエリ(この 1 が「+1」の部分)を実行したあと、通常はループの中で返ってきた各アイテムごとに N 回の追加クエリを発行してしまうときに発生します。実際には1 回のリクエストが、裏側ではひっそりと数十から数百回ものデータベースとの往復に変わってしまう、ということを意味します。テストデータの少ない環境ではうまく動作していても、本番トラフィックになると一気に破綻しがちです。
■N+1 Issue を検知するために特別な設定は必要ですか?
いいえ、必要ありません。すでに Sentry のパフォーマンスモニタリングを有効にしていれば、N+1 の検知は追加設定なしでそのまま利用できます。その上に Seer を追加することで、こうした問題を自動的に分析し修正することもできます。
■Seer が提案するコードが自分たちのスタイルやフレームワークに合わない場合はどうなりますか?
Seer が生成する修正は、あくまで「提案」であり、強制的に適用されるパッチではありません。マージする前にコードをレビューして、必要に応じて編集・加筆することができます。多くの開発者は Seer を「ものすごく高速で、常に起きていて、コーヒーブレイクを必要としない同僚」のような存在として扱っています。
■Seer は N+1 以外の問題にも役立ちますか?
はい。Seer は Sentry によって検知されたあらゆる Issue を分析します。たとえば、遅いエンドポイント、レイテンシのスパイク、非効率なループ、コストの高い API コール、サーバーエラーなどです。N+1 の検知は、より広いパターンの一例にすぎません。Seer は、なぜコードが遅いのか、そしてそれに対して何をすべきかを説明する手助けをしてくれます。
Original Page: Eliminating N+1 Queries with Seer’s Automated Root Cause Analysis
IchizokuはSentryと提携し、日本でSentry製品の導入支援、テクニカルサポート、ベストプラクティスの共有を行なっています。Ichizokuが提供するSentryの日本語サイトについてはこちらをご覧ください。またご導入についての相談はこちらのフォームからお気軽にお問い合わせください。


