DB歴10年が“最初に行う切り分け”を整理する
はじめに
SQLが遅いと感じたとき、
「どこから確認すればいいのか分からない」という悩みはよくあります。
私自身、Oracle と MySQL を中心に
DB設計・パフォーマンスチューニングに10年以上携わり、
現在は Web システムの PM として Laravel / PHP / Java / C# の開発・保守改善にも関わっていますが、
最初に行うべきなのは “遅延がどこで発生しているかの切り分け” だと感じています。
これは問題そのものを解決するものではありませんが、
調査を効率よく進めるために必要な工程です。
この記事では、
私が実務で使っている切り分けの流れを整理します。
1. 最初は「アプリ側かDB側か」を分ける
遅延の原因は大きく以下のどちらかです。
アプリ側の処理(PHP/Laravel/Java/C# など)
DB側の処理(SQL・統計情報・インデックス・スキーマなど)
まずはここを明確にすると、
調査が進めやすくなります。
2. 最初の10分で行う切り分け
Step1:処理全体が遅いのか、特定のSQLが遅いのか確認する
● 画面全体が遅い
→ アプリ側の処理時間が長い可能性が高い
(N+1、ループ過多、キャッシュ不使用など)
● 特定の操作だけ遅い
→ SQLが原因である可能性が高い
まずはここを見分けます。
Step2:遅いSQLを“特定するだけ”行う(改善は後)
ここでは改善しなくて大丈夫です。
何が遅いかを把握するだけで十分です。
【MySQLの場合】
■ SHOW FULL PROCESSLIST(現在の遅いSQLを確認)
SHOW FULL PROCESSLIST;
- Time が大きいものが遅延の対象
- Info にSQLが表示される
■ slow query log(定番)
slow_query_log = 1
long_query_time = 1
1秒以上かかったSQLをログに残せる。
■ performance_schema
必要に応じて利用。
【Oracleの場合】
■ v$session × v$sql
リアルタイムで遅いセッションを確認
SELECT sid, serial#, username, status, wait_class, seconds_in_wait
FROM v$session
WHERE username IS NOT NULL
ORDER BY seconds_in_wait DESC;
SQL本文
SELECT sql_id, sql_text
FROM v$sql
WHERE sql_id = '○○○';
■ AWRレポート
@?/rdbms/admin/awrrpt.sql
■ v$active_session_history
一時的な遅延を確認。
SELECT *
FROM v$active_session_history
ORDER BY sample_time DESC;
Step3:実行計画の「最初の3つ」だけ確認する
実行計画は深掘りし始めると長くなるので、
最初は次の3点だけで十分です。
① 行数推定(Cardinality / Rows)
→ 推定件数が大きくズレていないか
② WHERE句の選択性
→ 絞り込みが弱いSQLは遅くなる
③ 結合順序(JOIN順)
→ 大きな表から読んでしまっていないか
これを押さえると改善の方向性が決めやすくなります。
3. よくある勘違い
インデックスを追加すれば速くなる
状況によっては遅くなることもある。
Cost(コスト値)だけで判断できる
現実の性能と一致しないケースが多い。
SQLに原因があると決めつける
Laravel / PHP / Spring 側の処理が遅いことも多い。
統計情報は軽視して良い
ズレがあると実行計画が崩れる。
4. 実務で使っている切り分けの流れ(簡易版)
1. 全体遅延か部分遅延か確認
2. 遅いSQLを特定(改善は後)
3. WHERE句の選択性
4. 結合条件
5. インデックスの効き
6. 行数推定と統計情報
7. 必要に応じてスキーマの確認
この順番で見れば、調査の無駄が減ります。
まとめ
遅いSQLの調査では、まず 「どこで遅延が発生しているか」 を切り分けることで調査の方向性が明確になります。
その上で、実行計画・統計情報・スキーマなどを順番に確認していくことで、原因を特定しやすくなります。