この記事について
DBMSで、統計情報からコストを算出し、適切な実行計画を選択します。
インデックス貼っているのにフルスキャンが走っている!といった際は統計情報が不適切かもしれません。
Oracleで統計情報が適切か否かを調べる方法をまとめます。
DBA_TAB_STATS_HISTORYを参照し、統計情報の更新がされているか確認
下記のクエリを叩くと、新しい順で表ごとの統計情報の更新の履歴が確認できます。
SELECT * FROM DBA_TAB_STATS_HISTORY ORDER BY STATS_UPDATE_TIME DESC;
STATS_UPDATE_TIME
を見ると、いつ表の統計情報が更新されているかを確認できます。この更新日時が古い場合や存在しない場合は統計情報が更新されていない可能性があります。
DBA_TAB_STATISTICSを参照し、表の統計情報がいつ更新されているのか確認する
以下のクエリでオブジェクトごとの統計情報を取得します。
SELECT * FROM DBA_TAB_STATISTICS WHERE OWNER LIKE '自分が取得したい表のOWNER';
WHERE句は良い感じに自分の欲しいオブジェクトを絞れるように適宜変えてください。
NOT IN ('SYS', 'SYSTEM')
とかだけでも十分絞れそうです。
取得結果のSTALE_STATS
とLAST_ANALYZED
を参照します。
STALE_STATS
は以下3つの値を取ります。この列がYESかnullの場合は、統計情報が適切でない可能性が高いです。
- YES:統計情報が失効している
- NO:統計情報が失効していない(有効)
- null:統計情報がそもそもない
LAST_ANALYZED
は表が分析された最新の日付が入ります。この列の値がnullの場合も、統計情報が適切ではない可能性が高いです。
統計情報を取得したコマンドを確認する
大体の場合統計情報を取得するコマンドは分かると思います。もしコマンドが分からない場合は下記SQLで推察できるかもしれません。
以下コマンドでSQLのテキストに「STAT」が含まれるものを取得できます。これで「DBMS_STATS.GATHER_SCHEMA_STATS」があれば、コマンドの内容が見れると思います。
SELECT
*
FROM
DBA_HIST_SQLTEXT
INNER JOIN DBA_HIST_ACTIVE_SESS_HISTORY ON DBA_HIST_SQLTEXT.SQL_ID = DBA_HIST_ACTIVE_SESS_HISTORY.SQL_ID
WHERE
SQL_TEXT LIKE '%STAT%';