📙

【Oracle】「実行計画」についてわかりやすく解説!!

に公開

はじめに

Oracle DatabaseでSQLを実行し、結果を手元に取ってくるまでには以下の7つのステップがあります。
各ステップを理解すると、データベースの内部動作がイメージしやすくなり、チューニングやトラブルシューティングがスムーズになります。

この記事を読むとできること

  • SQL 実行からデータ取得までの内部処理フローを理解できる
  • オプティマイザや統計情報、実行計画の役割を把握できる
  • 実行計画の見方がわかり、チューニングやトラブル対応に活用できる

全体の流れ(7ステップ)

  1. SQLを送る

    • アプリケーションやクライアントツール(SQL*Plusなど)からDBに対してSQL文を送信。
    • 例:SELECT * FROM employees;
  2. パース(構文チェック)

    • SQL文を構文解析し「SELECT」「*」「FROM」などのトークン(キーワードや識別子など意味を持つ最小単位)に分解。
    • 構文解析で文法が正しいか確認し、内部的な構文木[1]を作成。
  3. リライト

    • SQL の論理構造を展開し(ビュー展開やシノニム解消)、最適な実行に適した形へ変換。
    • マテリアライズドビューやサブクエリのアンネスト、述語プッシュダウンで最適化前に整理。
  4. オプティマイザ(最適化)

    • 統計情報(テーブル行数、カーディナリティ、ヒストグラム)をもとに、複数の実行方法をコスト試算。

    • コストの例:

      • ディスク I/O 回数(バッファキャッシュにないブロックを読み込む回数)
      • CPU 時間(CPU での処理に要するおおよその時間)
      • ネットワーク転送量(リモート DB へのデータ送受信量)
    • 最小コストのアクセスパス(インデックススキャン vs フルテーブルスキャン)や結合方法(Nested Loops, Hash Joinなど)を選択。

  5. 実行計画の保存

    • ライブラリキャッシュに実行計画を登録し、同じSQL実行時に再利用。
  6. データの読み取りと処理

    • バッファキャッシュやディスクI/Oで必要なデータブロックを取得。
    • フィルタ条件の適用、JOINやソート、集約処理を実行。
  7. 結果を返す

    • フェッチされた行をクライアントに返却。

キーワード解説

SQL

  • 役割: データの取得・更新・削除・挿入を行う命令文。
  • ポイント: 最初のトリガー。文法チェックとパース処理がここから始まる。

統計情報

  • 役割: テーブルやインデックスの行数、データ分布を示すメタデータ。
  • ポイント: オプティマイザが「どのプランが速いか?」を判断する材料。DBMS_STATS.GATHER_* で定期的に最新化。

オプティマイザ

  • 役割: 統計情報と構文木を使い、コストモデルで最適な実行計画を選択するエンジン。
  • ポイント:
    1. 複数候補プラン(インデックススキャン/フルスキャンなど)を生成
    2. 各プランのコスト(I/O/CPU/ネットワーク)を比較
    3. 最小コストのプランを選択し、ライブラリキャッシュに登録

実行計画

  • 役割: オプティマイザが「効率よくデータを取得できる」と判断した計画(青写真)。
  • ポイント:
    • EXPLAIN PLAN FOR SELECT ...;
    • SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY()); で出力例を確認。
    • 実際の実行エンジンはこの手順に従い、データアクセス・結合・集約を行う。

参考資料

Oracle Databaseの「実行計画」についてわかりやすく語ってみた

最後に

最後まで読んで頂きありがとうございます!!
勉強や業務などで少しでも役に立てれば嬉しいです!!

まだまだ勉強中なので、不明点や指摘など気軽にコメントお願いします😄

脚注
  1. SQL文の構造をノードと枝で表現したツリー構造 ↩︎

Discussion