Javaエンジニアとして業務システムを開発していると、どうしても避けられないのがデータベースのパフォーマンス問題です。
特にSQL Serverを使用している場合、「SQLが遅い」と言われたときにまず注目すべきは 実行計画(Execution Plan) です。
今回は、私が実務で培ったSQL Serverにおける実行計画の基本的な読み解き方と、着目すべきポイントを共有します。
実行計画は、SQL ServerがSQLをどのように処理するかをステップごとに示したものです。
たとえば、どのテーブルをどの順序でアクセスするか、どのインデックスを利用するか、結合アルゴリズム(Nested Loops / Hash Match / Merge Join など)が記載されます。
確認方法としては以下があります:
実行前の推定計画:Ctrl+L
(SSMSで実行プランを表示)
実行後の実際の計画:Ctrl+M
を押してからSQLを実行
実務では、後者(実際の実行プラン)を確認するのが一般的です。
Table Scan
が頻発している場合は要注意です。大きなテーブルに対してインデックスが効かず、全件読み込んでいる可能性があります。
一方で、データ件数が少ない場合や範囲検索が広い場合は、フルスキャンが最適なケースもあるため「本当に遅いのか」を検証することが重要です。
SQL Serverではインデックス利用の有無が Index Seek(効率的な検索)か Index Scan(インデックス全走査)として現れます。
Seek
が出ていればインデックスが効いているサイン
Scan
が多発していればインデックス設計やクエリ記述を見直す余地あり
SQL Serverは結合に以下を使います:
Nested Loops:小規模データに有効。大きなテーブルで頻発すると遅くなる。
Hash Match:大規模データに強いがメモリ消費が大きい。
Merge Join:両テーブルがソート済みの場合に高速。
結合アルゴリズムが「期待通り」か確認することがチューニングの第一歩です。
実行計画では「Estimated Rows(推定行数)」と「Actual Rows(実際の行数)」が表示されます。
両者に大きな乖離がある場合、統計情報が古い可能性があります。SQL Serverでは 統計情報の更新(UPDATE STATISTICS) が重要です。
あるJava業務システムで、受注明細テーブルに対する検索が極端に遅くなっていました。
実行計画を確認すると Nested Loops が使用され、内側のテーブルが Table Scan されていました。
原因は、JOINキーにインデックスが存在していなかったこと。インデックスを追加することで、実行時間が 8秒 → 0.1秒 に改善されました。
さらに、統計情報を更新したことでクエリオプティマイザが正しく最適な実行計画を選択するようになりました。
SQLチューニングは「魔法」ではなく「論理と観察」の積み重ねです。
実行計画はその出発点であり、ボトルネックを可視化する強力なツールです。
Javaのロジックだけで解決できない問題に直面したとき、DBの内部動作に踏み込むことで、真のボトルネックに気づけることがあります。
SQL Serverの実行計画に慣れることは、フルスタックエンジニアへの大きな一歩です。