統計情報ってどのような情報?
統計情報ってどのような情報ですか?と聞かれた時、Oracleデータベースでは、具体的にどのような情報を指すか答えられますか?
統計情報と聞くと、表に格納されたデータの特性や、索引構成に関する情報を思い浮かべる人が多いと思います。しかし、統計情報には、CPU処理速度や、I/O速度などのシステムに関する情報や、V$SQLのような動的パフォーマンス表などの固定オブジェクトに関する情報も含まれます。表や列、索引というオブジェクトに対する統計だけでなく、下記の情報に対しても統計を取得していることを覚えておいてください。
統計情報を取得しないとどうなるの?
オラクルでは、どのような情報に対して統計を取得しているか、ご理解いただけたと思います。それでは、これらの統計情報を明示的に取得していない場合は、どのようになるかを考えてみましょう。
① オブジェクト統計を収集しなかった場合
Oracle Database 10g以降のバージョンでは、デフォルトで「自動統計収集」という機能が有効になっているため、設定を変更していない場合は、定期的に統計情報が自動収集されます。
また、自動統計収集を無効にした場合も、Oracle Database10gR2以降では、「動的サンプリング」という機能がデフォルトで有効になっているため、SQL実行時に統計を取得していない表を検出すると、自動的に統計情報が収集されます。
このように、新しいバージョンのデータベースでは、より実環境のデータの状態に適した実行計画を作成できるように、統計情報の取得漏れをなくすための仕組みがあります。
しかし、データの状態により実行計画が変動することを嫌い、敢えて統計情報を取得せずに運用しているシステムをたまにみかけます。
統計情報を取得していない環境で、自動統計収集も、動的サンプリングも無効にした場合は、デフォルト統計が使用されます。デフォルト統計では、「行の平均の長さは、100バイトとして計算する」など予め決められた値を使用します。しかし、ブロック数のように、実際の値が反映されるものもあるため、テーブルサイズが肥大化すると、デフォルト統計が変動して、実行計画が変わる場合があります。そのため、統計情報を取得しなければ、実行計画が変動しないという考えは間違っています。
コストベース・オプティマイザを使用する場合は、統計情報を取得しないことによるメリットはないので、必ず統計情報を取得してください。
② システム統計を収集しなかった場合
Oracle Database 10g以降のバージョンでは、CPU速度など、データベース起動時に自動的に取得される「NOWORKLOAD統計」と呼ばれるものと、明示的に設定しなければ取得されない「WORKLOAD統計」と呼ばれる、より詳細な統計情報の二種類があります。
オプティマイザが最適な実行計画を選択するためには、各問合せに必要なI/O、CPUリソースを正確に計算する必要があるので、「WORKLOAD統計」も取得することをお勧めします。
なお、I/OやCPUのパフォーマンス情報は、オブジェクト統計のように日々変動するものではないため、基本的には一度取得するだけで問題ありません。
ただし、負荷が殆どかかっていない時に取得してしまうと、ブロック読み込み時間が非常に速く算出されるなど、異常値が取得されてしまう可能性があるので、システムの負荷特性を考慮し、典型的なワークロードが流れている時に取得してください。
③ ディクショナリ統計を収集しなかった場合
Oracle Database 10g以降のバージョンでは、デフォルトで自動統計収集が有効であるため、設定を変更していない場合は、自動的に統計情報が収集されます。
なお、自動統計収集を無効にした環境では、デフォルト統計で実行計画を作成します。テーブル数が非常に多いシステムでは、デフォルト統計で見積もったコストと実際のコストがかけ離れてしまうため、不適切な実行計画を選択してしまい、性能問題が発生することがあります。
そのため、自動統計収集を無効にし、定期的にディクショナリ統計を取得しないシステムでは、構築後だけでなく、大幅なシステム変更により管理オブジェクトが増大した場合にもディクショナリ統計を取得してください。
④ 固定オブジェクト統計を収集しなかった場合
自動統計収集では取得されず、かつ動的サンプリングも機能しません。しかし、固定オブジェクト統計を取得していない場合は、statspackやAWRで性能情報を取得する時など、動的パフォーマンス表を参照する際に、不適切な実行計画を選択してしまう可能性があります。
固定オブジェクト統計も、オブジェクト統計のように日々変動するものではないため、構築後や、PSR適用時などメジャーアップデートを行った際に取得してください。