こんにちは!開発チームを支えるSREの先輩です。
毎日のように「なんだか最近、アプリ全体の応答速度が遅い気がする……」「特定の画面を開くときだけ、やたらとロードが長い……」なんて声に悩まされていませんか?
そして、いざ原因を探ろうとAPM(アプリケーションパフォーマンス監視)を開いてみても、「APIのレスポンスが遅いことは分かったけれど、結局どのSQLがボトルネックになっているのか分からない……」と、ログやスロークエリの海で溺れそうになった経験はありませんか?
もしあなたがそんなモヤモヤを抱えているなら、朗報です。今回は、Datadogの奥義とも言える機能「Database Monitoring(DBM)」を使って、インデックス不足やN+1問題といった「悪さをする遅いSQL」を秒速で特定し、チーム全体で鮮やかに解決していく手法を伝授します。
これをマスターすれば、もう勘や経験に頼ったデバッグとはお別れです。毎日の運用作業が劇的に楽になりますよ。さあ、一緒にその扉を開いていきましょう!
—
1. なぜ「普通のメトリクス監視」では遅いSQLを見つけられないのか?
まず、敵を知ることから始めましょう。
CPU使用率が跳ね上がっている、メモリが圧迫されている――こうしたサーバーの死活監視や一般的なメトリクス監視(CPU、Memory、Disk I/Oなど)は、いわば「今、病気で苦しんでいること」を教えてくれる体温計のようなものです。
しかし、体温計が高熱を示していても、「どのウィルスが、体のどこを攻撃しているのか」までは分かりませんよね。データベースの世界でも全く同じです。
「PostgreSQLのCPU使用率が90%です」とアラートが鳴っても、数千あるクエリのどれがそのCPUを食いつぶしているのか? アプリケーションのどのコードからそのクエリが発行されているのか? これを暴くのは、従来のログ監視や死活監視だけでは至難の業でした。
DBM(Database Monitoring)がもたらすパラダイムシフト
Datadog DBMは、データベースの内部深くまで侵入し、以下の情報を「リアルタイムかつ、コードと結びつけて」可視化してくれます。
- 個々のSQL文ごとの実行時間、実行回数、負荷の総量
- SQLがデータベース内部で何に時間を奪われているのか(待機イベントの分析)
- 実際の実行計画(Execution Plan)のビジュアル化
- APMのトレース(APIリクエスト)とSQLの完璧な紐付け
これによって、「どのAPIが、どの遅いSQLを呼び出し、DBのどこで詰まっているのか」が一本の線でつながるのです。
—
2. 5分で完了!Datadog DBMの基礎セットアップ(PostgreSQL編)
「難しそうだな……」と思いましたか?
ご安心ください。Datadog DBMの導入は、正しく手順を踏めば驚くほどスムーズです。ここでは、現場で最もよく使われるPostgreSQLを例に、精度高く動作確認(Hello Worldならぬ「Hello Slow Query!」)を行うまでのステップを優しく解説します。
ステップ1: データベース側での権限設定と拡張機能
まずは、DatadogのエージェントがPostgreSQLの内部統計情報を安全に覗き見できるように、専用の読み取り専用ユーザーを作成し、必要な拡張機能を有効化します。
PostgreSQLに管理者権限で接続し、以下のSQLを実行してください。
— 1. 監視用の専用ユーザーを作成
CREATE USER datadog WITH PASSWORD ‘your_secure_password’;
— 2. 統計情報へのアクセス権限を付与
GRANT pg_monitor TO datadog;
— ※古いバージョン(PG 9.6など)の場合は、個別のスキーマやテーブルに対する権限調整が必要です
— 3. クエリの正規化や統計情報を取得するために不可欠な拡張機能を有効化
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
> 先輩のワンポイントアドバイス:
> `pg_stat_statements` は、PostgreSQLのパフォーマンスチューニングにおける「心臓部」です。これが有効になっていないと、クエリの集計が正しく行われないため、設定漏れに注意してください!
ステップ2: Datadog Agentの設定
次に、データベースと同一サーバー(またはサイドカーとして動く)Datadog Agentの設定ファイル(`conf.d/postgres.d/conf.yaml`)を編集します。
init_config:
instances:
- host: localhost
port: 5432
username: datadog
password: ‘your_secure_password’
# DBM機能を有効化する魔法のフラグ
collect_statement_metrics: true
collect_database_size_metrics: true
collect_tables_stats: true
# 実行計画(Execution Plan)の収集を有効化(これが最強の武器になります)
plans:
enabled: true
設定を保存したら、Datadog Agentを再起動します。
sudo systemctl restart datadog-agent
これでセットアップは完了です! Datadogのダッシュボード([Datadog UI] > [Databases])を開いてみてください。見慣れたデータベースのアイコンとともに、メトリクスが流れ込んできているはずです。
—
3. 現場で発見!「インデックス不足」と「N+1問題」の暴き方
セットアップが終わったら、いよいよ実戦です。DBMを使って、よくある2大パフォーマンスキラーをどのように特定するのかを見ていきましょう。
ケースA:全表スキャン(Sequential Scan)の恐怖を暴く(インデックス不足)
ある日、ユーザー一覧画面を開くたびにアプリが重くなると報告を受けたとします。DBMの「Databases」画面を開き、「Queries」タブに直行しましょう。
ここで、「Execution Time(実行時間の総量)」の降順でSQLをソートします。すると、ひときわ目立つクエリが見つかりました。
SELECT FROM users WHERE email LIKE ‘%example.com’;
このクエリをクリックすると、DBMの真骨頂である「Query Details」が表示されます。
1. 待機イベント(Wait States)の確認:
CPUを消費しているのか、それともディスクからの読み込み(Disk I/O)で待たされているのかが一目でわかります。前方一致ではない `LIKE ‘%…’` のせいで、PostgreSQLが数百万行のテーブルを最初から最後まで舐め回す「Sequential Scan(全表スキャン)」を起こし、ディスクI/Oネックになっていることがグラフで一目瞭然になります。
2. 実行計画(Execution Plan)の可視化:
DBM上には、そのクエリが実際どのように実行されたかのツリー構造(あるいは視覚的なプラン)が表示されます。「Cost」が跳ね上がっているノードにマウスを合わせれば、どこに負荷が集中しているかが一撃でわかります。
【解決へのアプローチ】
原因が分かれば対策は簡単です。B-treeインデックスでは前方一致の部分一致検索を効率化できないため、必要に応じてGINインデックスやpg_trgm(拡張機能)を検討するか、クエリの仕様自体を見直す(メールアドレスのドメインごとのカラムを分けるなど)という判断を、開発チームと共通の画面を見ながら即座に下すことができます。
—
ケースB:APM連携で見抜く「N+1問題」
オブジェクト指向のORM(ActiveRecord、Hibernate、Prismaなど)を使っていると、知らず知らずのうちに踏んでしまうのが「N+1問題」です。
「1回の画面表示で、なぜかデータベースへのクエリが500回発行されている……」なんて悪夢ですね。
Datadog DBMは、APM(Application Performance Monitoring)とシームレスに統合されています。
- APMのトレース画面から、「おや、このAPIリクエスト、やけにDBクエリの数が多いぞ」と気づく。
- そのトレースからワンクリックで「このリクエストによって発行されたすべてのSQL」をDBM側で一覧表示できる。
- 同じ構造のSQLが、パラメータだけを変えて何百回も連続して発行されている様子が、タイムライン上に美しい(そして恐ろしい)階段状のグラフとして描画される。
【解決へのアプローチ】
「あ、ここはORMの `includes` や `eager_load`(JOIN一括取得)を書き忘れているな」と、コードの該当箇所(トレースにはファイル名やメソッド名まで紐づいています)を特定し、数行のコード修正でデータベースへの負荷を95%以上削減することができます。
—
4. 開発チームとSREが手を取り合う「持続可能な改善ワークフロー」
素晴らしいツールを導入しても、それを使いこなす文化がなければ宝の持ち腐れです。最後に、私たちSREと開発チームがどのようなワークフローでDBパフォーマンスを改善していくべきか、その理想形をお伝えします。
1. SREが「ウォッチドッグ」として異常を検知する
Datadogの「Watchdog(AIによる自動異常検知)」を活用し、「いつもと違う挙動の遅いSQL」や「新しくデプロイされたコードによって追加された非効率なクエリ」を自動で検知し、SREや担当チームのSlackへ通知するようにします。
2. 共通言語としてDBMのリンクを貼る
Slack通知やJiraチケットには、必ず該当するDatadog DBMのクエリ詳細画面へのパーマリンクを添えます。「ここが重いです」ではなく、「このクエリが、この実行計画でボトルネックになっています」と、客観的なデータ(Visual Execution PlanとWait States)を共通の土俵にするのです。
3. スプリントの定例で「Top 5 悪者クエリ」を潰す
週に一度、あるいはスプリントの振り返りの際に、DBMで「今週最も負荷をかけたSQL Top 5」を確認し、ちょっとしたインデックスの追加やクエリのリファクタリングをバックログに積む習慣をつけます。
—
まとめ:遅いSQLの恐怖から解放された世界へ
今回は、Datadog Database Monitoring (DBM) を使って遅いSQLを徹底的に特定し、チームで改善していくためのアプローチをご紹介しました。
- ツールの役割: 従来の体温計のようなメトリクス監視から脱却し、どのSQLが、なぜ遅いのかを深部まで透視する。
- 基礎セットアップ: 権限付与と `pg_stat_statements` の有効化、そしてAgentの設定だけで、世界が変わる。
- 実践: インデックス不足による全表スキャンや、APMと連携したN+1問題を鮮やかに特定する。
これをマスターすれば、「アプリが重い」という漠然とした恐怖に怯える必要はもうありません。データに基づいた冷静でスマートな最適化を行えるようになります。
さあ、今すぐあなたの環境でもDBMを有効にして、最初の一番遅いクエリを駆逐しに行きましょう! 毎日の開発・運用ライフが、驚くほど軽やかになりますよ。