実行計画とは?
既に保守現場でSQLのパフォーマンスチューニングの話が出た時に
Oracle Gold資格を保有しながらも
「実行計画、統計情報、オプティマイザ・・・」
様々な言葉が飛び交い、話についていけないときがありました。
こんなの試験に出なかったじゃないか!!
と嘆いてもしょうがないので再勉強し、
「実行計画」についてまとめてみました。
これを読んだらチューニングマスターだぜ!
とまではいかないですが、
- 実行計画という言葉についてイメージが湧く
- 簡単なパフォーマンス問題なら原因がわかる
程度にはまとめてみました。
結論から
最初に結論から実行計画とは何かというと
SQLでデータを取得する時にテーブルの検索する順番、使用するインデックスなど決める手順書
です。
まず、前提として時間がかかるような複雑なSQLというのは複数のテーブル、複数のテーブル、複数のインデックスから成り立っているのが通常です。なので、
- テーブルを検索する順番
- インデックスを利用するかしないか
で大きく処理時間が変わってしまいます。
テーブルを検索する順番や
インデックスを使用するかしないか
などが書かれた手順書が
実行計画
なのです。
実行計画をディズニーランドで例えてみる
いきなりですが、実行計画をディズニーランドで例えてみます。
SQLの応答時間を早くする
ということを
目的のアトラクション全てに短時間乗る
と置き換えると
実行計画とは
アトラクションに乗る順番
のようなものだと思ってください。
例えば、
「スペースマウンテン、スプラッシュマウンテン、ハニーハント・・・・」
全部乗りたい!
といったときに、
ディズニーランドに詳しい人は
「ハニーハントは今、イベント中だから朝一で並んだ方が良いよ。スペースマウンテンは午後からでも乗れる、位置関係は・・・(略)」
などなど、
アトラクションの時間帯ごとの混み具合、アトラクションの位置関係などが頭に入っているので、この順番でいくと一番最短で乗れるよ!
っていってくれます。
この時の
「ハニーハントは今、イベント中だから朝一で並んだ方が良いよ。スペースマウンテンは午後からでも乗れる、位置関係は・・・(略)」
の
アトラクションを乗る順番
がOracleでいうところの「実行計画」にあたります。
ちなみに
アトラクションを乗る順番を実行計画
とすると
ディズニーランドオタク=オプティマイザ
アトラクションの混雑具合・位置関係等=統計情報
となります。こちらもセットで覚えておくと良いと思います。
実行計画をみたい!
実行計画っていう概念はわかったけど、実体を見てみたい!
以下の赤枠が実行計画です。
もう少し正確に言うと緑枠のSQLに対する実行計画が上記赤枠の箇所になります。
緑枠のSQLに対し、
どのテーブルから先に検索して、
インデックスをどのように使えばより
早くデータを取得できるかを表しているのが赤枠になります。
※実行計画の出し方は当サイトでは解説しませんが、
様々な出し方があるので、詳しくはこちらを見てください。
参考URL:実行計画の確認方法
実際の現場でどんなときに使う?
では実際の現場ではどのように活用しているのでしょうあ?
簡単な例だと
実行計画を元にCOSTという箇所が高いところをみます。
例えば、COSTが高い場所が
TABLE ACCESS FULL
となっていたら、インデックスを使用していないので、
インデックスを作成すれば改善の見込み可能性が大いにあります。
先ほど紹介した例だとCOSTが高いところはないので、
改善の見込みはなさそうです。(例が悪くてすみません。。)
ちなみに一番上とその下はCOSTが「5」となっていますが、どちらもすべてのCOSTの合計値なので、今回の場合は上から3番目以下のコストをみます。
実行計画はいつ作成される?
実行計画はいつ作成されるのか?
実行計画はSQLが実行されるたびに、毎回作成されます。
以上(おい)
実行計画を変えることはできるか?
実行計画を変えたい場合はどうするのでしょうか?
結論から言うと、
100%思い通りに変えることはできません。
ただ、一部を変えることはできます。
変え方はいろいろありますが、有名どころですと3つあります。
- 統計情報を変える
- INDEXを作成する
- ヒント句を使用する
以下で順次紹介します。
統計情報を変える
実行計画は「統計情報」を元に作成するので、
統計情報を大きく変えることによって変わってくれることがあります。
先ほどディズニーランドの例で
アトラクション混雑具合などが統計情報と説明しました。
例えば
期間限定イベントのアトラクションの期間が終了した!
なんてことになったら、少し混雑具合が減って、
アトラクションの乗る順番を変更したりしますよね。
それと同じです。(わかりずらい?汗)
インデックスを使う
先ほども紹介しましたが、フルスキャンとなっているテーブルに対して
インデックスを作れば、高い確率でオプティマイザが反応してそのインデックスを使用するようにしてくれます。
インデックスはディズニーランドの話で例えると
ファストパスみたいなものだと思ってください。
ディズニーランドオタクに(オプティマイザ)だったら絶対使いますよね。
素人でも使うか。。。
ヒント句を使用する
SELECT分にヒント句を使用すれば強制的に変えることができます。
一番有名なのがインデックスを使用させるヒント句です。
例)以下の例はテーブル:TB1に対して、IX_Aのヒント句を使用すると宣言しています。
select /+INDEX(a IX_A)/ * from TB1 a where a.col1 = 変数;
他にも色々なヒント句があります。
終わりに
いかがでしょうか?
感覚的な話をすると、概要だけ聞いても実際問題にぶち当たってみるのが一番良いとは思います。(元も子もない。。。)
冒頭に説明した
- テーブルを検索する順番
- インデックスを利用するかしないか
で大きく処理時間が変わってしまう。
ということを実感している人とそうでない人では理解度が変わってくると思います。
しかし、
パフォーマンスチューニングはエンジニア人生を送っていれば、必ず直面するので、あせらず、その時を待ちましょう!(なんじゃそりゃ?)
最後まで読んで頂きありがとうございます。