統計情報とは?
* テーブル、インデックスなどがどのような状態なのかを表している情報。
例
* データ量 => テーブルにデータが何件格納されているか => 1行の平均サイズは、どの位なのか * データの分布状況 => テーブル項目にはどのような値が多く格納されているか など
統計情報は何のために使うのか
* DBのオプティマイザは複数の実行プランを作成し、その中で最適な実行プランを選択するのだが、 その選択基準となるのが、統計情報である。 ※なお、オプティマイザや実行プランの詳細な説明については、以下の記事を参照のこと。http://blogs.yahoo.co.jp/dk521123/28850809.html
統計情報更新の必要性
* 統計情報が、DBの現状とは異なる状況を表している場合、パフォーマンスが悪い実行プランを選択し 処理遅延を起こす可能性がある点
例
実データが1億件で、その中から5件取得するSQLを実行したとする... 仮に、統計情報が古く、対象テーブルに対して5件しか格納されていないという統計情報になっていた場合、 DBのオプティマイザは「どうせ5件しかないんだから、5件取得するのには、インデックスなんか使わずに フルスキャンでええやろ」と判断してしまう可能性がある。 →しかし、実データは1億件なので、この結果、パフォーマンスが悪くなる。 この例の原因は、統計情報が古いので、更新していれば、正しい実行プランを選択する可能性が高くなる
使用上の注意
* デフォルトは、自動更新になっている。 * 時には、手動で行う必要がある。詳細は以下を参照のこと。http://blogs.msdn.com/b/jpsql/archive/2012/04/19/on.aspx
統計情報更新の適切なタイミング
以下の参考文献は、Oracleが対象だが他のDBにも同じことが言えそうなので、メモっとく。 ■要約 データの特性によって、どのようなタイミングで統計情報を収集すればよいかが決まる。 => そのため、まずは対象テーブルが、どのような特性に分類されるのかを知る必要がある
[1] データ量がほぼ一定
例えば、あまり変更がないマスターテーブル等? => 定期的に統計情報を取得する必要はない => DBの設定で自動統計収集に任せて良さそう
[2] 一貫した増加傾向
例えば、長期間に保存して置かなければならない注文テーブル等? => 定期的に統計情報を更新する必要がある ※注意 統計情報の更新には、CPUなどハードウェアリソースを使用するため、 業務処理が少ない時間帯(例えば、夜間や土日・祝日など)にバッチ処理などで更新した方がいい
[3] 一定間隔での増加/減少の繰り返し
例えば、バッチ処理を行うなど、一定間隔での増加/減少を繰り返すテーブル等 => データの特性として、実データと統計情報の乖離が発生し易い => データ量が最大になるタイミングで更新するといい
[4] 不確定な変動
例えば、景気などの影響する部品などの発注テーブル?等 => データの特性として、実データと統計情報の乖離が発生し易い (ただし、[3]とは異なり、データ量が最大になるタイミングが分からない) => 自動統計収集を無効化する => 記事には、以下のように書いてあるけど、現実的にはそもそも予想できないのだから難しそう 動的サンプリングは、Oracleの機能(?)だから他のDBでは難しい?? * 将来的な表の最大件数を再現したテストデータで統計情報を取得し、固定化することで対応 * 本番環境に近いデータ分布も意識してテストデータを作成する必要 * テストデータを用意することが難しい場合は、動的サンプリングを使用することを検討
参考文献
http://enterprisezine.jp/dbonline/detail/4253http://oracletech.jp/products/pickup/000371.html