統計情報とは

ORACLEにおける統計情報とはデータベースや表、索引の特性(データサイズやデータの分布等)をまとめたものであり、以下の4種類の統計情報があります。

表に対する統計
表のサイズ、行数、1行当たり平均サイズ等

表内の列に対する統計
列データの種類数、データ分布(ヒストグラム)等

索引に対する統計
索引のサイズ、階層数、クラスタ化係数等

システムに対する統計(9i~)
サーバのI/OやCPUの処理能力等

つまり、統計情報とは使用しているサーバやデータベースの特性を数値で表したものといえます。


統計情報はなぜ必要か

一番大きな目的は最適な実行計画を立てられる可能性を高めるためです。 逆にいえば発行する全てのSQLがヒント等により最適な実行計画で固定されていれば統計情報を取得する必要性は大幅に低下します (統計情報はパフォーマンス調査等にも使えるため全くないというわけではありません)。 また、実行計画が決まってしまえばその実行計画の通りに処理されるだけなので実行計画が決まった後の処理時間には統計情報は影響しません。

統計情報が有効なケース

例えば、「select * from tab1 where col1 > 10」というSQLに対して実行計画を立てる場合を考えます。 tab1のアクセス方法にはテーブルフルキャンかcol1のインデックススキャンのどちらかが選択できるとした場合、 テーブルフルスキャンとインデックススキャンのどちらが速いかは「col1 > 10」の検索条件の選択率が何%になるかに大きく依存することになります。 (ちなみに、マニュアルにも記載のある一般論でいえば15%以下の選択率であれば索引アクセスが高速とされます)

もし列に対する統計情報がなければ「col1 > 10」の選択率はORACLEは予測できないため、インデックススキャンとテーブルフルスキャンどちらが早いかを判断することはできません (ダイナミックサンプリング機能はここでは考慮しません)。 統計情報を使用しないRBOというロジックにより実行計画が立てられた場合実際に早いかどうかは別としてインデックスを使う実行計画になります。

それに対して実態に即した統計情報が取得されていれば検索条件の選択率が何%であるかをORACLEが機械的に予測できるため、 テーブルフルスキャンの処理時間のほうがインデックスアクセススキャンよりも早いと予想すればテーブルスキャンを選択することができます。

統計情報が悪影響を及ぼすケース

統計情報は「統計情報を収集した時点の統計」のため、統計情報を収集した時点から大きくデータが変動している場合誤った選択率等から実行計画が立てられます。 このため、統計情報と実際のデータに大きな乖離が発生する前に定期的に統計情報を収集しなおしたほうがよい場合もあります。 なお、10g以降のバージョンではデフォルトで平日夜間と休日にある程度データの変動があったオブジェクトに対して自動的に統計情報を収集しなおすジョブが起動します。

統計情報に関する注意

・最適な実行計画が選択されるとは限らない
実態に即した正確な統計情報が収集されていたとしてもORACLEが最も早い実行計画を選択するとは限りません。 逆に統計情報がないほうが早い実行計画が選択されてしまう可能性さえあります。特定のSQLのみ遅くなる場合は該当SQLに対してヒントやアウトライン等による実行計画の固定を検討し、 個々のSQLに対する対処が困難であれば実行計画の選定に影響するパラメータの変更等を検討、テストします。

・統計情報を収集しなおすと実行計画が変わる可能性がある
実行計画はパフォーマンスに影響する非常に大きな要因であり不適切な実行計画に変わると今まで1分で終わっていたクエリが1時間かかるようになるといった事象が発生することも珍しくありません。 上述の通り統計情報を最新にしたとしてもパフォーマンスがよい実行計画が選択されるかはわからないため、本番運用中に統計の自動収集ジョブを有効にするなどで統計情報が常に変化する状態にしておくことはパフォーマンス悪化の可能性というリスクが常に発生していることを認識しておく必要があります。 本番運用開始前の段階で統計情報を定期的に収集すべき表とすべきでない表を切り分けし、基本的には一部を除き統計情報は良好なパフォーマンスが得られている状態でロックしておいたほうがよいでしょう。

・システム統計情報を取得すると開発環境と本番環境で実行計画が変わる可能性が高くなる
システム統計情報を取得することでサーバのI/O性能等を考慮した実行計画が立てられることになり、性能が大きく異なる開発環境等と異なる実行計画が選択される可能性が高くなります。

・統計情報のサンプリング率は100%でなくともよい
統計情報のサンプリング率は表が大きい場合は100%のデータをサンプリングしなくともほぼ正確な統計となります。 ただし、値の種類(DBA_TAB_COLUMNS.NUM_DISTINCT)の統計値はサンプリング率を低くすることで影響が出やすいので 値の種類毎のデータ件数に極端な偏りがある列を持つ表等ではサンプリング率を多めにしたほうがよい場合があります。

・ヒストグラム統計を取得した場合ハードパースの負荷が増大する
ヒストグラム統計を取得することでORACLEはより正確な実行計画を立てやすくなりますが、 ハードパース時の再帰SQLでヒストグラム統計を参照するというオーバーヘッドが追加されCPU負荷が増大するのでハードパースが多発している環境では注意が必要です。

関連ディクショナリ

・現在の統計情報
DBA_TAB_STATISTICS
DBA_IND_STATISTICS
DBA_TAB_COL_STATISTICS
DBA_PART_COL_STATISTICS
DBA_SUBPART_COL_STATISTICS

・過去の統計情報(10g~)
DBA_OPTSTAT_OPERATIONS
DBA_TAB_STATS_HISTORY

マニュアル

概要
パフォーマンス・チューニングガイド
カスタム検索

★ORACLE案件承ります
▼ORACLE掲示板