読者です 読者をやめる 読者になる 読者になる

山下寛人オフィシャルブログ

オイシックス株式会社 執行役員 システム本部長 山下寛人の公式ブログです。

Oracleの実行計画

OracleではSQLを実行する際に実行計画を作ります。この実行計画はどのテーブルをどのインデックスを使用して検索し、他のテーブルとジョインするときのアルゴリズムはどうするといったもので、SQLのパフォーマンスを大きく左右します。インデックスを使う、使わないでSQLの検索結果が全然返ってこなくなったり一瞬で結果が出たりします。

この実行計画は現在のOracleではテーブルの統計情報に基づいて作成されます。それぞれのレコード数や、値のばらつき具合などに基づきます。例えばレコード数が多く、値がほとんどのレコードで違っている場合はインデックスを使ったほうが早く検索できます。いっっぽうレコード数が少なく値の種類が少ない場合はインデックスを使わずフルスキャンしたほうが早く検索できる場合があります。ジョインのアルゴリズムもネステッド・ループ・ジョインやソート・マージジョインなどがあります。統計情報は定期的にOracleが取得します。テーブルを作ると自動的にスケジュールされるので通常は意識することはありません。

これをコストベースオプティマイゼーションと言いますがこいつが困りものなときがあります。一つはテストサーバーで実行計画が確認できないということ。テストサーバーは通常レコード数が少ないので実行計画が本番と全然異なる場合があります。本番サーバーで見てみないといけません。

また、まれに最適化した結果逆にパフォーマンスが悪くなる場合があります。昨日まで普通に動いていたSQLが急にCPUを100%使い続けて結果が返ってこなくなったり、DBサーバーの全体ロードアベレージを上げてしまうことがあります。10gR2では今まで何度か、数えるほどですが、こういう現象が起こりました。新しいバージョンでは改善されているのでしょうか。

これを予防するとなると、Oracleの中の話になるのでなかなかの難題です。コンテスト形式でみんなで考えてみようと思います。