データベースを利用したシステムでは、SELECT文の実行速度が全体のパフォーマンスに大きく影響します。
画面表示が遅い、バッチ処理が終わらない、APIの応答が悪いといった問題の多くは、SELECT文の遅延が原因で発生します。
本記事では、SELECT文が遅いと感じた際に、実務で確実に確認すべきポイントを10項目に整理して解説します。
特定のデータベース製品に依存しない考え方を中心に、Oracle、MySQL、PostgreSQL など、どの環境でも共通して役立つ内容としています。
1. 実行計画を確認しているか
SELECT文が遅い場合、最初に確認すべきなのは実行計画です。
実行計画を見ずにSQLを修正するのは、地図を見ずに目的地へ向かうようなものです。
確認すべき点は以下です。
- フルテーブルスキャンになっていないか
- 想定したインデックスが使用されているか
- 結合順序が不自然になっていないか
実行計画は「なぜ遅いのか」を客観的に示してくれる唯一の情報です。
SELECT文が遅い原因を特定するうえで、実行計画の確認は欠かせません。
実行計画の基本的な見方や、フルテーブルスキャン・インデックススキャンの判断方法については、以下の記事で詳しく解説しています。
2. WHERE句にインデックスが効く書き方になっているか
インデックスが存在していても、SQLの書き方によっては使用されません。
以下のような書き方は注意が必要です。
- 列に対して関数を適用している
- 暗黙的な型変換が発生している
- LIKE ‘%文字列%’ の前方一致以外の検索
インデックスは「列そのもの」を条件にした場合に最も効果を発揮します。
SELECT文の性能改善では、インデックスの有無だけでなく、「効く形で使われているか」が重要です。
インデックスが作成されていても利用されない典型的な原因については、以下の記事で詳しく解説しています。

3. 必要以上の列を取得していないか
SELECT * を使用している場合、不要な列まで取得している可能性があります。
特に以下のケースでは影響が顕著です。
- 列数が多いテーブル
- LOB型や大きな文字列列が含まれている
- ネットワーク越しに結果を返す処理
取得する列は、実際に使用するものだけに絞ることが基本です。
4. 結合条件が適切に記述されているか
JOIN句の条件が不十分だと、想定以上のデータが結合され、処理時間が急激に増加します。
確認ポイントは以下です。
- 主キーと外部キーで結合されているか
- 結合条件がWHERE句に紛れ込んでいないか
- 結合キーにインデックスがあるか
結合はSQLの中でも特にパフォーマンス影響が大きい部分です。
5. 件数が多すぎるデータを一度に取得していないか
大量データを一度に取得すると、データベースだけでなくアプリケーション側にも負荷がかかります。
以下の対策を検討します。
- LIMIT や FETCH FIRST の利用
- ページング処理の導入
- 集計結果のみ取得する設計への変更
「本当にその件数が必要か」を見直すことが重要です。
6. サブクエリの使い方が適切か
サブクエリは便利ですが、使い方を誤ると性能劣化の原因になります。
特に注意すべき点は以下です。
- 相関サブクエリになっていないか
- JOINに書き換え可能ではないか
- 実行計画上、繰り返し評価されていないか
意図せず行単位で処理されているケースは少なくありません。
7. 統計情報が最新の状態か
統計情報が古いと、データベースは誤った実行計画を選択します。
以下のような状況では要注意です。
- データ件数が大きく変動した
- 一括更新・削除を行った
- 長期間メンテナンスされていない
定期的な統計情報の更新は、安定した性能維持に欠かせません。
8. インデックスの設計が適切か
インデックスは「存在すれば良い」ものではありません。
以下の点を確認します。
- WHERE句やJOIN条件で使われている列か
- 複合インデックスの列順は適切か
- 使われていないインデックスが増えていないか
インデックスの過不足は、SELECTだけでなく更新性能にも影響します。
9. 排他ロックや競合が発生していないか
SELECT文であっても、ロック待ちにより遅くなる場合があります。
特に以下のケースは注意が必要です。
- 更新系SQLと同時に実行されている
- トランザクションが長時間開きっぱなし
- 分離レベルが高く設定されている
性能問題が必ずしもSQL単体に起因しないことも理解しておく必要があります。
10. SQL以外の要因を切り分けているか
SELECT文が遅いように見えても、原因が別にあるケースもあります。
例としては以下が挙げられます。
- ネットワーク遅延
- アプリケーション側の処理時間
- DBサーバのCPUやI/O逼迫
SQLの実行時間と、処理全体の時間は分けて考えることが重要です。
よくある質問(Q & A)
- インデックスを追加すれば必ず速くなりますか
-
必ずしも速くなるとは限りません。条件に合わないインデックスは使用されず、逆に更新性能を悪化させることもあります。
- 実行計画が毎回変わるのは問題ですか
-
データ量や条件によって変わる場合は問題ありませんが、極端に性能が変動する場合は対策が必要です。
- SELECT * は絶対に使ってはいけませんか
-
小規模な検証や管理用SQLでは問題ありませんが、本番処理では避けるのが基本です。
- JOINとサブクエリはどちらが速いですか
-
ケースによりますが、実行計画を確認した上で判断する必要があります。
- SQLチューニングはどこまでやるべきですか
-
体感や業務影響が出るレベルの遅延がある場合に、優先的に対応すべきです。
まとめ
SELECT文が遅い場合、闇雲にSQLを書き換えるのではなく、
実行計画・インデックス・データ量・ロック状況といった基本ポイントを順序立てて確認することが重要です。
今回紹介した10項目をチェックすることで、原因の切り分けがしやすくなり、再発防止にもつながります。
