Oracle Database 統計情報を利用した実行計画の最適化

こんにちは。バックエンドエンジニアの小佐野です。


前回に引き続きOracleDatabaseの実行計画と統計情報について解説していきます。

実行計画の作成について簡単に説明すると、SQL文をオプティマイザが解釈し、統計情報に基づいて実行計画が作成されます。

作成された実行計画に従ってデータベースからレコードを抽出する流れとなります。
オプティマイザはOracleDatabaseの機能の1つで、実行計画の作成を担当します。

適切な実行計画が作成されないと、SQL文の要求通りにレコードを抽出できたとしても処理時間が増大することになります。

実行計画には、テーブルにアクセスする順序、検索の方法(インデックス検索/全量検索)などが記載されています。

SQL文の要求を満たす実行計画は複数想定されますが、処理時間が最適になる実行計画はテーブルに登録されているレコードの分布によって変わってきます。

レコードの分布をまとめているのが統計情報です。

前回の記事で書きましたが、抽出するレコードの割合が少ない場合はインデックス検索が有効なので
統計情報から、対象となるレコードの割合が少なくなる見込みの場合は実行計画はインデックス検索が、そうでない場合は、全量検索が選択されます。

テーブルにアクセスする順序の判定にも統計情報が使用され、レコード数が早い段階で絞り込めるようにテーブルのアクセス順序が決定されます。

SQL文にHINT句を記載することで実行計画をある程度ユーザーの想定通りに作成させることも可能ですが、version11以降は非推奨となっています。

(HINT句については今回は割愛します。非推奨ですが、version12ではHINT句により実行計画が変わるようです。)
したがって、統計情報を最新の状態に保つことで、最適な実行計画が作成されます。

一般的に統計情報は夜間バッチなどで更新されます。
しかし、データベースをリストアした場合などは自動的に更新されない場合がありますので、手動で統計情報を最新化する必要があります。

例えば、半期に1回、データベースをテーブルごと世代管理で移動するシステムであれば、過去分に移動したテーブルはその日の夜間バッチまで統計情報に不整合がある状態となり、その状態で過去テーブルにアクセスするSQLを実行すると、最適でない実行計画が作成され、処理時間が増大する、といった事象が発生します。

世代管理を扱う場合は、テーブルだけではなく統計情報にも注意してください。

次回はSQL段階でのチューニングについて記載していこうと思います。