Oracle

Oracleのオプティマイザとは?実際の現場でどのように活用しているか?

オプティマイザとは?

Oracleのオプティマイザ

特に保守など、既に稼働しているサービスにおいてはパフォーマンス問題はよく聞く話だと思います。

その中で実行計画、統計情報、オプティマイザ・・・などなど色々な言葉が飛び交っていると思います。

今回は私が取得しているOracle Goldの知識や職場で経験したことも踏まえて「オプティマイザ」について情報をまとめてみました。

これを読んだらオプティマイザマスターだぜ!

ってことにはなりませんが、

パフォーマンスチューニングの話が出た時に話についていけるようになるようになると思います。

オプティマイザとは何か?

まずは結論から

オプティマイザとは

テーブルを検索する順番などを決めて、目的のデータを素早く取得するためのOracleに搭載されているソフトウェア

です

そもそも、複雑で時間がかかるSQLというのは複数のテーブル、複数のインデックスから成り立っているのが通常です。なので、

  • テーブルを検索する順番
  • インデックスを利用するかしないか

などの判断で、大きく処理時間が変わってしまいます。

それを決定してくれるのがオプティマイザなのです。

※上記の”SQLを検索する順番”や”インデックスを利用するかしないか”のことを「実行計画」と呼んでいます。

オプティマイザをディズニーランドで例える

いきなりですが、オプティマイザをディズニーランドで例えてみます。

オプティマイザとは

アトラクションを乗る順番を決めて連れて行ってくれるディズニーランドオタク(芸人?)のような存在だと思ってみるとわかりやすいかもしれません。

例えば、

「スペースマウンテン、スプラッシュマウンテン、ハニーハント・・・・」

全部乗りたい!

といったときに、

ディズニーランドオタクは

「ハニーハントは今、イベント中だから朝一で並んだ方が良いよ。スペースマウンテンは午後からでも乗れる、位置関係は・・・(略)」

などなど、

アトラクションの時間帯ごとの混み具合、アトラクションの位置関係などが頭に入っているので、この順番でいくと一番最短で乗れるよ!

っていってくれます。

オプティマイザも同じで

このSQLでデータを取得したい!

というと、オプティマイザはデータベースの量、使用頻度、などを考慮して

どの順番でSQLを検索してどのインデックスを使えば良いかを判断してくれるのです。

ちなみに

ディズニーランドオタクをオプティマイザとすると

アトラクションを乗る順番=実行計画

アトラクションの混み具合、位置関係等=統計情報

オプティマイザをこの目でみたい?

概要はわかったけど、オプティマイザは実際みることはできないのか?

オプティマイザは最初の説明のとおり「ソフトウェア」なので実体はありませんが、

オプティマイザの仕事を少し可視化すると「実行計画」で確認することができます。

先ほど紹介しましたが、

  • SQLを検索する順番
  • インデックスを利用するかしないか

などのことを実行計画といいます。

オプティマイザがしっかりと機能するとこの実行計画が最適になります。

以下が実行計画です。

詳しくは解説しませんが、

左側が改善前の実行計画、右側が改善後の実行計画です。オプティマイザがしっかり仕事をこなすと更に実行計画がシンプルになったります。

Oracle Database 12c Release 2のオプティマイザ(PDF)から抜粋

オプティマイザを使いたい?

オプティマイザってどうやって使うの?

というとオプティマイザはOracleに搭載されているものなので、SQLを実行したら勝手にオプティマイザが動きます。

なので、通常、意識的に使うことはありません。

しかし、オプティマイザはバージョンごとに複数用意されていて、旧バージョンのオプティマイザをヒント句にSQLに直接指定すれば使用できるようになっています。

実際オプティマイザを使用した例

実際、先ほど紹介したヒント句を現場で利用した例を紹介します。

私が保守している現場で、Oacleのバージョンの入れ替えがありました。

バージョンを入れ替えた途端、特定のSQLパフォーマンスが低下しました。

どうやら新しいバージョンのオプティマイザだと実行計画の立て方が悪いのが原因のようでした。

そのため、対象SQLに対して ヒント句を利用し、

バージョンアップまえのSQLを実行したところ、パフォーマンスが元の速さに改善しました。

ちなみに以下のようにヒント句を入れます。

(例:最新バージョンが12cで11gリリース1(11.1.0.6)のヒント句を入れる場合)


SELECT /*+ optimizer_features_enable('11.1.0.6') */ employee_id, last_name
FROM    employees
ORDER BY employee_id;

最後に

いかがでしょうか?

実際、経験しないとわからない部分があるかと
思いますが、

要はオプティマイザは

  • データベースからデータを取得するために道筋を決めるガイド
  • ヒント句を使用すれば、対象のSQLに対して、旧バージョンのオプティマイザを使用できる

くらい覚えておくと
今後の役に立つかもしれません。

参考URL

Oracle® Database SQLチューニング・ガイド

関連記事