10 April, 1998 Updated
PCDN OracleWG S.Yamazaki
コストベース・アプローチ(CBO)を選択する上で欠かせないのが、表・索引の統計です。いくら、索引を作成しようが、ヒントを付けて実行しようが、統計が採られていないと何の役にも役にも立ちません。
統計を採るためには、ANALYZEコマンドの発行が必要であり、ここでは、ANALYZEコマンド発行のタイミングや、その使用方法となどについて説明します。
| ANALYZEの役割 |
|---|
オプティマイザが利用するために、オブジェクト(表、索引、パーティーション、クラスタなど)の統計情報を収集します。収集された統計データはsys所有のディクショナリに格納されます。
また、ヒストグラムを格納したり、連鎖している行情報、さらにはオブジェクトの構造を調べることもできます。以降それぞれについて説明していきます。
| 統計の収集 |
|---|
表の統計
表の統計では以下の情報を得ることができます。({USER|ALL|DBA}_TABLESディクショナリ)
| 項目 | {USER|ALL|DBA}_TABLESの列 |
|---|---|
| 行数 | NUM_ROWS |
| 使用ブロック数 | BLOCKS |
| 未使用ブロック数 | EMPTY_BLOCKS |
| 空き領域の平均バイト数 | AVG_SPACE |
| 連鎖行数 | CHAIN_CNT |
| 平均行数 | AVG_ROW_LEN |
ANALYZE TABLE table_name COMPUTE STATISTICS; 完全な行数の統計を採ります。
ANALYZE TABLE table_name ESTIMATE STATISTICS SAMPLE 5000 ROWS; 5,000行でサンプリングします。
ANALYZE TABLE table_name ESTIMATE STATISTICS SAMPLE 40%; 40%でサンプリングします。
注意:SAMPLEで、半分以上(50%,実際の行数の半分)の値を指定すると、完全な統計を採ります。
索引の統計
索引の統計では以下の情報を得ることができます。({USER|ALL|DBA}_INDEXESディクショナリ)
ただし、明示的に索引の統計をしなくても、表の統計によって、関連している索引の統計も採られます。
| 項目 | {USER|ALL|DBA}_INDEXESの列 |
|---|---|
| リーフブロックまでの深さ | BLEVEL |
| リーフブロック数 | LEAF_BLOCKS |
| 重複していない行数 | DISTICT_KEYS |
| 索引値ごとの平均リーフブロック数 | AVG_LEAF_BLOCKS_PER_KEY |
| 索引値ごとの平均データブロック数 | AVG_DATA_BLOCKS_PER_KEY |
| クラスタ系数 | CLUSTERING_FACTOR |
ANALYZE INDEXES index_name COMPUTE STATISTICS;
列の統計
列の統計では以下の情報を得ることができます。({USER|ALL|DBA}_TAB_COLUMNSディクショナリ)
これは、列のヒストグラムを採るときの手段に用いられます。
ただし、索引統計と同じように明示的に列の統計をしなくても、表の統計によって、関連している列の統計も採られます。
(R8.0からUSER|ALL|DBA _TAB_COL_STATISTICS表が別に用意されております。R8.0ならば、こちらを使用してください。)
| 項目 | {USER|ALL|DBA}_TAB_COLUMNSの列 |
|---|---|
| 列内での重複していない数 | NUM_DISTINCT |
| 列内の最小値 | LOW_VALUE |
| 列内の最大値 | HIGH_VALUE |
| 列の密度 | DENSITY |
| 列内のNULLの数 | NUM_NULLS |
| 列のヒストグラム内のバケット数 | NUM_BUCKETS |
| 項目 | {USER|ALL|DBA}_TAB_HISTOGRAMSの列 |
|---|---|
| バケット番号 | ENDPOINTNUMBER |
| バケット用に正規化された終値 | ENDPOINT_VALUE |
ANALYZE TABLE table_name COMPUTE STATISTICS FOR COLUMNS colums_name SIZE xx (default 75);
| 統計情報の削除 |
|---|
統計情報を削除したい場合、例えば、ある特定の表をRBOに戻したいときは、いつでも削除できます。
ANALYZE TABLE table_name DELETE STATISTICS;
このコマンドを発行すると、データ・ディクショナリ表から、該当テーブルの統計及び索引、ヒストグラムの統計もすべて削除されます。
| DBMSパッケージの利用 |
|---|
ANALYZEコマンドと等価なものとして、次のパッケージが用意されています。(このパッケージを利用するには、ANALYZE権限が必要です。)
| メンテナンス |
|---|
CBOはANALYZEコマンドによって採られた統計情報を基に実行計画を立てます。よって、統計情報の数値に誤り(統計値と実際の行数が違う場合など)があると、最適な実行計画が選択されない場合もあります。
厳密に統計を採って、最適化したい場合などは、定期的にANALYZEコマンドを発行する必要があります。
ただし、ANALYZEコマンド等によって表や索引が分析されたあとは、共有プールにある分析された依存関係のある共有SQL文はフラッシュされますので、注意が必要です。
以下は、定期的にANALYZEコマンドを発行するために、DBMS_UTILITYパッケージを使ってJOBに登録した例です。独自に応用して実行されるようお勧めします。
-- 毎週月曜日 午前1時 (AM 1:00)にスキーマ配下のオブジェクトすべてにANALYZEコマンド発行。
set serveroutput on
DECLARE
what VARCHAR2(200) := 'SYS.DBMS_UTILITY.ANALYZE_SCHEMA(''スキーマ'',''COMPUTE'',NULL,NULL);';
next_date DATE := TRUNC(SYSDATE);
interval VARCHAR2(200) := 'NEXT_DAY(TRUNC(SYSDATE),2)+1/24';
BEGIN
DBMS_JOB.ISUBMIT(2001,what,next_date,interval);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(sqlcode || ' '|| sqlerrm(sqlcode));
END;
/
|